Name the magic constants, wrap long lines
[qemu] / hw / esp.c
1 /*
2  * QEMU ESP/NCR53C9x emulation
3  *
4  * Copyright (c) 2005-2006 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "hw.h"
25 #include "block.h"
26 #include "scsi-disk.h"
27 #include "sun4m.h"
28 /* FIXME: Only needed for MAX_DISKS, which is probably wrong.  */
29 #include "sysemu.h"
30
31 /* debug ESP card */
32 //#define DEBUG_ESP
33
34 /*
35  * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
36  * also produced as NCR89C100. See
37  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
38  * and
39  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
40  */
41
42 #ifdef DEBUG_ESP
43 #define DPRINTF(fmt, args...) \
44 do { printf("ESP: " fmt , ##args); } while (0)
45 #else
46 #define DPRINTF(fmt, args...)
47 #endif
48
49 #define ESP_MASK 0x3f
50 #define ESP_REGS 16
51 #define ESP_SIZE (ESP_REGS * 4)
52 #define TI_BUFSZ 32
53 /* The HBA is ID 7, so for simplicitly limit to 7 devices.  */
54 #define ESP_MAX_DEVS      7
55
56 typedef struct ESPState ESPState;
57
58 struct ESPState {
59     qemu_irq irq;
60     BlockDriverState **bd;
61     uint8_t rregs[ESP_REGS];
62     uint8_t wregs[ESP_REGS];
63     int32_t ti_size;
64     uint32_t ti_rptr, ti_wptr;
65     uint8_t ti_buf[TI_BUFSZ];
66     int sense;
67     int dma;
68     SCSIDevice *scsi_dev[MAX_DISKS];
69     SCSIDevice *current_dev;
70     uint8_t cmdbuf[TI_BUFSZ];
71     int cmdlen;
72     int do_cmd;
73
74     /* The amount of data left in the current DMA transfer.  */
75     uint32_t dma_left;
76     /* The size of the current DMA transfer.  Zero if no transfer is in
77        progress.  */
78     uint32_t dma_counter;
79     uint8_t *async_buf;
80     uint32_t async_len;
81     void *dma_opaque;
82 };
83
84 #define ESP_TCLO   0x0
85 #define ESP_TCMID  0x1
86 #define ESP_FIFO   0x2
87 #define ESP_CMD    0x3
88 #define ESP_RSTAT  0x4
89 #define ESP_WBUSID 0x4
90 #define ESP_RINTR  0x5
91 #define ESP_WSEL   0x5
92 #define ESP_RSEQ   0x6
93 #define ESP_WSYNTP 0x6
94 #define ESP_RFLAGS 0x7
95 #define ESP_WSYNO  0x7
96 #define ESP_CFG1   0x8
97 #define ESP_RRES1  0x9
98 #define ESP_WCCF   0x9
99 #define ESP_RRES2  0xa
100 #define ESP_WTEST  0xa
101 #define ESP_CFG2   0xb
102 #define ESP_CFG3   0xc
103 #define ESP_RES3   0xd
104 #define ESP_TCHI   0xe
105 #define ESP_RES4   0xf
106
107 #define CMD_DMA 0x80
108 #define CMD_CMD 0x7f
109
110 #define CMD_NOP      0x00
111 #define CMD_FLUSH    0x01
112 #define CMD_RESET    0x02
113 #define CMD_BUSRESET 0x03
114 #define CMD_TI       0x10
115 #define CMD_ICCS     0x11
116 #define CMD_MSGACC   0x12
117 #define CMD_SATN     0x1a
118 #define CMD_SELATN   0x42
119 #define CMD_SELATNS  0x43
120 #define CMD_ENSEL    0x44
121
122 #define STAT_DO 0x00
123 #define STAT_DI 0x01
124 #define STAT_CD 0x02
125 #define STAT_ST 0x03
126 #define STAT_MI 0x06
127 #define STAT_MO 0x07
128 #define STAT_PIO_MASK 0x06
129
130 #define STAT_TC 0x10
131 #define STAT_PE 0x20
132 #define STAT_GE 0x40
133 #define STAT_IN 0x80
134
135 #define INTR_FC 0x08
136 #define INTR_BS 0x10
137 #define INTR_DC 0x20
138 #define INTR_RST 0x80
139
140 #define SEQ_0 0x0
141 #define SEQ_CD 0x4
142
143 #define CFG1_RESREPT 0x40
144
145 #define CFG2_MASK 0x15
146
147 #define TCHI_FAS100A 0x4
148
149 static int get_cmd(ESPState *s, uint8_t *buf)
150 {
151     uint32_t dmalen;
152     int target;
153
154     dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
155     target = s->wregs[ESP_WBUSID] & 7;
156     DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
157     if (s->dma) {
158         espdma_memory_read(s->dma_opaque, buf, dmalen);
159     } else {
160         buf[0] = 0;
161         memcpy(&buf[1], s->ti_buf, dmalen);
162         dmalen++;
163     }
164
165     s->ti_size = 0;
166     s->ti_rptr = 0;
167     s->ti_wptr = 0;
168
169     if (s->current_dev) {
170         /* Started a new command before the old one finished.  Cancel it.  */
171         scsi_cancel_io(s->current_dev, 0);
172         s->async_len = 0;
173     }
174
175     if (target >= MAX_DISKS || !s->scsi_dev[target]) {
176         // No such drive
177         s->rregs[ESP_RSTAT] = STAT_IN;
178         s->rregs[ESP_RINTR] = INTR_DC;
179         s->rregs[ESP_RSEQ] = SEQ_0;
180         qemu_irq_raise(s->irq);
181         return 0;
182     }
183     s->current_dev = s->scsi_dev[target];
184     return dmalen;
185 }
186
187 static void do_cmd(ESPState *s, uint8_t *buf)
188 {
189     int32_t datalen;
190     int lun;
191
192     DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
193     lun = buf[0] & 7;
194     datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
195     s->ti_size = datalen;
196     if (datalen != 0) {
197         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC;
198         s->dma_left = 0;
199         s->dma_counter = 0;
200         if (datalen > 0) {
201             s->rregs[ESP_RSTAT] |= STAT_DI;
202             scsi_read_data(s->current_dev, 0);
203         } else {
204             s->rregs[ESP_RSTAT] |= STAT_DO;
205             scsi_write_data(s->current_dev, 0);
206         }
207     }
208     s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
209     s->rregs[ESP_RSEQ] = SEQ_CD;
210     qemu_irq_raise(s->irq);
211 }
212
213 static void handle_satn(ESPState *s)
214 {
215     uint8_t buf[32];
216     int len;
217
218     len = get_cmd(s, buf);
219     if (len)
220         do_cmd(s, buf);
221 }
222
223 static void handle_satn_stop(ESPState *s)
224 {
225     s->cmdlen = get_cmd(s, s->cmdbuf);
226     if (s->cmdlen) {
227         DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
228         s->do_cmd = 1;
229         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_CD;
230         s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
231         s->rregs[ESP_RSEQ] = SEQ_CD;
232         qemu_irq_raise(s->irq);
233     }
234 }
235
236 static void write_response(ESPState *s)
237 {
238     DPRINTF("Transfer status (sense=%d)\n", s->sense);
239     s->ti_buf[0] = s->sense;
240     s->ti_buf[1] = 0;
241     if (s->dma) {
242         espdma_memory_write(s->dma_opaque, s->ti_buf, 2);
243         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_ST;
244         s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
245         s->rregs[ESP_RSEQ] = SEQ_CD;
246     } else {
247         s->ti_size = 2;
248         s->ti_rptr = 0;
249         s->ti_wptr = 0;
250         s->rregs[ESP_RFLAGS] = 2;
251     }
252     qemu_irq_raise(s->irq);
253 }
254
255 static void esp_dma_done(ESPState *s)
256 {
257     s->rregs[ESP_RSTAT] |= STAT_IN | STAT_TC;
258     s->rregs[ESP_RINTR] = INTR_BS;
259     s->rregs[ESP_RSEQ] = 0;
260     s->rregs[ESP_RFLAGS] = 0;
261     s->rregs[ESP_TCLO] = 0;
262     s->rregs[ESP_TCMID] = 0;
263     qemu_irq_raise(s->irq);
264 }
265
266 static void esp_do_dma(ESPState *s)
267 {
268     uint32_t len;
269     int to_device;
270
271     to_device = (s->ti_size < 0);
272     len = s->dma_left;
273     if (s->do_cmd) {
274         DPRINTF("command len %d + %d\n", s->cmdlen, len);
275         espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
276         s->ti_size = 0;
277         s->cmdlen = 0;
278         s->do_cmd = 0;
279         do_cmd(s, s->cmdbuf);
280         return;
281     }
282     if (s->async_len == 0) {
283         /* Defer until data is available.  */
284         return;
285     }
286     if (len > s->async_len) {
287         len = s->async_len;
288     }
289     if (to_device) {
290         espdma_memory_read(s->dma_opaque, s->async_buf, len);
291     } else {
292         espdma_memory_write(s->dma_opaque, s->async_buf, len);
293     }
294     s->dma_left -= len;
295     s->async_buf += len;
296     s->async_len -= len;
297     if (to_device)
298         s->ti_size += len;
299     else
300         s->ti_size -= len;
301     if (s->async_len == 0) {
302         if (to_device) {
303             // ti_size is negative
304             scsi_write_data(s->current_dev, 0);
305         } else {
306             scsi_read_data(s->current_dev, 0);
307             /* If there is still data to be read from the device then
308                complete the DMA operation immeriately.  Otherwise defer
309                until the scsi layer has completed.  */
310             if (s->dma_left == 0 && s->ti_size > 0) {
311                 esp_dma_done(s);
312             }
313         }
314     } else {
315         /* Partially filled a scsi buffer. Complete immediately.  */
316         esp_dma_done(s);
317     }
318 }
319
320 static void esp_command_complete(void *opaque, int reason, uint32_t tag,
321                                  uint32_t arg)
322 {
323     ESPState *s = (ESPState *)opaque;
324
325     if (reason == SCSI_REASON_DONE) {
326         DPRINTF("SCSI Command complete\n");
327         if (s->ti_size != 0)
328             DPRINTF("SCSI command completed unexpectedly\n");
329         s->ti_size = 0;
330         s->dma_left = 0;
331         s->async_len = 0;
332         if (arg)
333             DPRINTF("Command failed\n");
334         s->sense = arg;
335         s->rregs[ESP_RSTAT] = STAT_ST;
336         esp_dma_done(s);
337         s->current_dev = NULL;
338     } else {
339         DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
340         s->async_len = arg;
341         s->async_buf = scsi_get_buf(s->current_dev, 0);
342         if (s->dma_left) {
343             esp_do_dma(s);
344         } else if (s->dma_counter != 0 && s->ti_size <= 0) {
345             /* If this was the last part of a DMA transfer then the
346                completion interrupt is deferred to here.  */
347             esp_dma_done(s);
348         }
349     }
350 }
351
352 static void handle_ti(ESPState *s)
353 {
354     uint32_t dmalen, minlen;
355
356     dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
357     if (dmalen==0) {
358       dmalen=0x10000;
359     }
360     s->dma_counter = dmalen;
361
362     if (s->do_cmd)
363         minlen = (dmalen < 32) ? dmalen : 32;
364     else if (s->ti_size < 0)
365         minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
366     else
367         minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
368     DPRINTF("Transfer Information len %d\n", minlen);
369     if (s->dma) {
370         s->dma_left = minlen;
371         s->rregs[ESP_RSTAT] &= ~STAT_TC;
372         esp_do_dma(s);
373     } else if (s->do_cmd) {
374         DPRINTF("command len %d\n", s->cmdlen);
375         s->ti_size = 0;
376         s->cmdlen = 0;
377         s->do_cmd = 0;
378         do_cmd(s, s->cmdbuf);
379         return;
380     }
381 }
382
383 static void esp_reset(void *opaque)
384 {
385     ESPState *s = opaque;
386
387     memset(s->rregs, 0, ESP_REGS);
388     memset(s->wregs, 0, ESP_REGS);
389     s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
390     s->ti_size = 0;
391     s->ti_rptr = 0;
392     s->ti_wptr = 0;
393     s->dma = 0;
394     s->do_cmd = 0;
395 }
396
397 static void parent_esp_reset(void *opaque, int irq, int level)
398 {
399     if (level)
400         esp_reset(opaque);
401 }
402
403 static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
404 {
405     ESPState *s = opaque;
406     uint32_t saddr;
407
408     saddr = (addr & ESP_MASK) >> 2;
409     DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
410     switch (saddr) {
411     case ESP_FIFO:
412         if (s->ti_size > 0) {
413             s->ti_size--;
414             if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
415                 /* Data in/out.  */
416                 fprintf(stderr, "esp: PIO data read not implemented\n");
417                 s->rregs[ESP_FIFO] = 0;
418             } else {
419                 s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
420             }
421             qemu_irq_raise(s->irq);
422         }
423         if (s->ti_size == 0) {
424             s->ti_rptr = 0;
425             s->ti_wptr = 0;
426         }
427         break;
428     case ESP_RINTR:
429         // Clear interrupt/error status bits
430         s->rregs[ESP_RSTAT] &= ~(STAT_IN | STAT_GE | STAT_PE);
431         qemu_irq_lower(s->irq);
432         break;
433     default:
434         break;
435     }
436     return s->rregs[saddr];
437 }
438
439 static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
440 {
441     ESPState *s = opaque;
442     uint32_t saddr;
443
444     saddr = (addr & ESP_MASK) >> 2;
445     DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
446             val);
447     switch (saddr) {
448     case ESP_TCLO:
449     case ESP_TCMID:
450         s->rregs[ESP_RSTAT] &= ~STAT_TC;
451         break;
452     case ESP_FIFO:
453         if (s->do_cmd) {
454             s->cmdbuf[s->cmdlen++] = val & 0xff;
455         } else if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
456             uint8_t buf;
457             buf = val & 0xff;
458             s->ti_size--;
459             fprintf(stderr, "esp: PIO data write not implemented\n");
460         } else {
461             s->ti_size++;
462             s->ti_buf[s->ti_wptr++] = val & 0xff;
463         }
464         break;
465     case ESP_CMD:
466         s->rregs[saddr] = val;
467         if (val & CMD_DMA) {
468             s->dma = 1;
469             /* Reload DMA counter.  */
470             s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
471             s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
472         } else {
473             s->dma = 0;
474         }
475         switch(val & CMD_CMD) {
476         case CMD_NOP:
477             DPRINTF("NOP (%2.2x)\n", val);
478             break;
479         case CMD_FLUSH:
480             DPRINTF("Flush FIFO (%2.2x)\n", val);
481             //s->ti_size = 0;
482             s->rregs[ESP_RINTR] = INTR_FC;
483             s->rregs[ESP_RSEQ] = 0;
484             break;
485         case CMD_RESET:
486             DPRINTF("Chip reset (%2.2x)\n", val);
487             esp_reset(s);
488             break;
489         case CMD_BUSRESET:
490             DPRINTF("Bus reset (%2.2x)\n", val);
491             s->rregs[ESP_RINTR] = INTR_RST;
492             if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
493                 qemu_irq_raise(s->irq);
494             }
495             break;
496         case CMD_TI:
497             handle_ti(s);
498             break;
499         case CMD_ICCS:
500             DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
501             write_response(s);
502             break;
503         case CMD_MSGACC:
504             DPRINTF("Message Accepted (%2.2x)\n", val);
505             write_response(s);
506             s->rregs[ESP_RINTR] = INTR_DC;
507             s->rregs[ESP_RSEQ] = 0;
508             break;
509         case CMD_SATN:
510             DPRINTF("Set ATN (%2.2x)\n", val);
511             break;
512         case CMD_SELATN:
513             DPRINTF("Set ATN (%2.2x)\n", val);
514             handle_satn(s);
515             break;
516         case CMD_SELATNS:
517             DPRINTF("Set ATN & stop (%2.2x)\n", val);
518             handle_satn_stop(s);
519             break;
520         case CMD_ENSEL:
521             DPRINTF("Enable selection (%2.2x)\n", val);
522             break;
523         default:
524             DPRINTF("Unhandled ESP command (%2.2x)\n", val);
525             break;
526         }
527         break;
528     case ESP_WBUSID ... ESP_WSYNO:
529         break;
530     case ESP_CFG1:
531         s->rregs[saddr] = val;
532         break;
533     case ESP_WCCF ... ESP_WTEST:
534         break;
535     case ESP_CFG2:
536         s->rregs[saddr] = val & CFG2_MASK;
537         break;
538     case ESP_CFG3 ... ESP_RES4:
539         s->rregs[saddr] = val;
540         break;
541     default:
542         break;
543     }
544     s->wregs[saddr] = val;
545 }
546
547 static CPUReadMemoryFunc *esp_mem_read[3] = {
548     esp_mem_readb,
549     esp_mem_readb,
550     esp_mem_readb,
551 };
552
553 static CPUWriteMemoryFunc *esp_mem_write[3] = {
554     esp_mem_writeb,
555     esp_mem_writeb,
556     esp_mem_writeb,
557 };
558
559 static void esp_save(QEMUFile *f, void *opaque)
560 {
561     ESPState *s = opaque;
562
563     qemu_put_buffer(f, s->rregs, ESP_REGS);
564     qemu_put_buffer(f, s->wregs, ESP_REGS);
565     qemu_put_be32s(f, &s->ti_size);
566     qemu_put_be32s(f, &s->ti_rptr);
567     qemu_put_be32s(f, &s->ti_wptr);
568     qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
569     qemu_put_be32s(f, &s->sense);
570     qemu_put_be32s(f, &s->dma);
571     qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ);
572     qemu_put_be32s(f, &s->cmdlen);
573     qemu_put_be32s(f, &s->do_cmd);
574     qemu_put_be32s(f, &s->dma_left);
575     // There should be no transfers in progress, so dma_counter is not saved
576 }
577
578 static int esp_load(QEMUFile *f, void *opaque, int version_id)
579 {
580     ESPState *s = opaque;
581
582     if (version_id != 3)
583         return -EINVAL; // Cannot emulate 2
584
585     qemu_get_buffer(f, s->rregs, ESP_REGS);
586     qemu_get_buffer(f, s->wregs, ESP_REGS);
587     qemu_get_be32s(f, &s->ti_size);
588     qemu_get_be32s(f, &s->ti_rptr);
589     qemu_get_be32s(f, &s->ti_wptr);
590     qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
591     qemu_get_be32s(f, &s->sense);
592     qemu_get_be32s(f, &s->dma);
593     qemu_get_buffer(f, s->cmdbuf, TI_BUFSZ);
594     qemu_get_be32s(f, &s->cmdlen);
595     qemu_get_be32s(f, &s->do_cmd);
596     qemu_get_be32s(f, &s->dma_left);
597
598     return 0;
599 }
600
601 void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
602 {
603     ESPState *s = (ESPState *)opaque;
604
605     if (id < 0) {
606         for (id = 0; id < ESP_MAX_DEVS; id++) {
607             if (s->scsi_dev[id] == NULL)
608                 break;
609         }
610     }
611     if (id >= ESP_MAX_DEVS) {
612         DPRINTF("Bad Device ID %d\n", id);
613         return;
614     }
615     if (s->scsi_dev[id]) {
616         DPRINTF("Destroying device %d\n", id);
617         scsi_disk_destroy(s->scsi_dev[id]);
618     }
619     DPRINTF("Attaching block device %d\n", id);
620     /* Command queueing is not implemented.  */
621     s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
622 }
623
624 void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
625                void *dma_opaque, qemu_irq irq, qemu_irq *reset)
626 {
627     ESPState *s;
628     int esp_io_memory;
629
630     s = qemu_mallocz(sizeof(ESPState));
631     if (!s)
632         return NULL;
633
634     s->bd = bd;
635     s->irq = irq;
636     s->dma_opaque = dma_opaque;
637
638     esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
639     cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory);
640
641     esp_reset(s);
642
643     register_savevm("esp", espaddr, 3, esp_save, esp_load, s);
644     qemu_register_reset(esp_reset, s);
645
646     *reset = *qemu_allocate_irqs(parent_esp_reset, s, 1);
647
648     return s;
649 }