Break up vl.h.
[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), also
36  * 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 STAT_DO 0x00
85 #define STAT_DI 0x01
86 #define STAT_CD 0x02
87 #define STAT_ST 0x03
88 #define STAT_MI 0x06
89 #define STAT_MO 0x07
90
91 #define STAT_TC 0x10
92 #define STAT_PE 0x20
93 #define STAT_GE 0x40
94 #define STAT_IN 0x80
95
96 #define INTR_FC 0x08
97 #define INTR_BS 0x10
98 #define INTR_DC 0x20
99 #define INTR_RST 0x80
100
101 #define SEQ_0 0x0
102 #define SEQ_CD 0x4
103
104 static int get_cmd(ESPState *s, uint8_t *buf)
105 {
106     uint32_t dmalen;
107     int target;
108
109     dmalen = s->rregs[0] | (s->rregs[1] << 8);
110     target = s->wregs[4] & 7;
111     DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
112     if (s->dma) {
113         espdma_memory_read(s->dma_opaque, buf, dmalen);
114     } else {
115         buf[0] = 0;
116         memcpy(&buf[1], s->ti_buf, dmalen);
117         dmalen++;
118     }
119
120     s->ti_size = 0;
121     s->ti_rptr = 0;
122     s->ti_wptr = 0;
123
124     if (s->current_dev) {
125         /* Started a new command before the old one finished.  Cancel it.  */
126         scsi_cancel_io(s->current_dev, 0);
127         s->async_len = 0;
128     }
129
130     if (target >= MAX_DISKS || !s->scsi_dev[target]) {
131         // No such drive
132         s->rregs[4] = STAT_IN;
133         s->rregs[5] = INTR_DC;
134         s->rregs[6] = SEQ_0;
135         qemu_irq_raise(s->irq);
136         return 0;
137     }
138     s->current_dev = s->scsi_dev[target];
139     return dmalen;
140 }
141
142 static void do_cmd(ESPState *s, uint8_t *buf)
143 {
144     int32_t datalen;
145     int lun;
146
147     DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
148     lun = buf[0] & 7;
149     datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
150     s->ti_size = datalen;
151     if (datalen != 0) {
152         s->rregs[4] = STAT_IN | STAT_TC;
153         s->dma_left = 0;
154         s->dma_counter = 0;
155         if (datalen > 0) {
156             s->rregs[4] |= STAT_DI;
157             scsi_read_data(s->current_dev, 0);
158         } else {
159             s->rregs[4] |= STAT_DO;
160             scsi_write_data(s->current_dev, 0);
161         }
162     }
163     s->rregs[5] = INTR_BS | INTR_FC;
164     s->rregs[6] = SEQ_CD;
165     qemu_irq_raise(s->irq);
166 }
167
168 static void handle_satn(ESPState *s)
169 {
170     uint8_t buf[32];
171     int len;
172
173     len = get_cmd(s, buf);
174     if (len)
175         do_cmd(s, buf);
176 }
177
178 static void handle_satn_stop(ESPState *s)
179 {
180     s->cmdlen = get_cmd(s, s->cmdbuf);
181     if (s->cmdlen) {
182         DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
183         s->do_cmd = 1;
184         s->rregs[4] = STAT_IN | STAT_TC | STAT_CD;
185         s->rregs[5] = INTR_BS | INTR_FC;
186         s->rregs[6] = SEQ_CD;
187         qemu_irq_raise(s->irq);
188     }
189 }
190
191 static void write_response(ESPState *s)
192 {
193     DPRINTF("Transfer status (sense=%d)\n", s->sense);
194     s->ti_buf[0] = s->sense;
195     s->ti_buf[1] = 0;
196     if (s->dma) {
197         espdma_memory_write(s->dma_opaque, s->ti_buf, 2);
198         s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
199         s->rregs[5] = INTR_BS | INTR_FC;
200         s->rregs[6] = SEQ_CD;
201     } else {
202         s->ti_size = 2;
203         s->ti_rptr = 0;
204         s->ti_wptr = 0;
205         s->rregs[7] = 2;
206     }
207     qemu_irq_raise(s->irq);
208 }
209
210 static void esp_dma_done(ESPState *s)
211 {
212     s->rregs[4] |= STAT_IN | STAT_TC;
213     s->rregs[5] = INTR_BS;
214     s->rregs[6] = 0;
215     s->rregs[7] = 0;
216     s->rregs[0] = 0;
217     s->rregs[1] = 0;
218     qemu_irq_raise(s->irq);
219 }
220
221 static void esp_do_dma(ESPState *s)
222 {
223     uint32_t len;
224     int to_device;
225
226     to_device = (s->ti_size < 0);
227     len = s->dma_left;
228     if (s->do_cmd) {
229         DPRINTF("command len %d + %d\n", s->cmdlen, len);
230         espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
231         s->ti_size = 0;
232         s->cmdlen = 0;
233         s->do_cmd = 0;
234         do_cmd(s, s->cmdbuf);
235         return;
236     }
237     if (s->async_len == 0) {
238         /* Defer until data is available.  */
239         return;
240     }
241     if (len > s->async_len) {
242         len = s->async_len;
243     }
244     if (to_device) {
245         espdma_memory_read(s->dma_opaque, s->async_buf, len);
246     } else {
247         espdma_memory_write(s->dma_opaque, s->async_buf, len);
248     }
249     s->dma_left -= len;
250     s->async_buf += len;
251     s->async_len -= len;
252     if (to_device)
253         s->ti_size += len;
254     else
255         s->ti_size -= len;
256     if (s->async_len == 0) {
257         if (to_device) {
258             // ti_size is negative
259             scsi_write_data(s->current_dev, 0);
260         } else {
261             scsi_read_data(s->current_dev, 0);
262             /* If there is still data to be read from the device then
263                complete the DMA operation immeriately.  Otherwise defer
264                until the scsi layer has completed.  */
265             if (s->dma_left == 0 && s->ti_size > 0) {
266                 esp_dma_done(s);
267             }
268         }
269     } else {
270         /* Partially filled a scsi buffer. Complete immediately.  */
271         esp_dma_done(s);
272     }
273 }
274
275 static void esp_command_complete(void *opaque, int reason, uint32_t tag,
276                                  uint32_t arg)
277 {
278     ESPState *s = (ESPState *)opaque;
279
280     if (reason == SCSI_REASON_DONE) {
281         DPRINTF("SCSI Command complete\n");
282         if (s->ti_size != 0)
283             DPRINTF("SCSI command completed unexpectedly\n");
284         s->ti_size = 0;
285         s->dma_left = 0;
286         s->async_len = 0;
287         if (arg)
288             DPRINTF("Command failed\n");
289         s->sense = arg;
290         s->rregs[4] = STAT_ST;
291         esp_dma_done(s);
292         s->current_dev = NULL;
293     } else {
294         DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
295         s->async_len = arg;
296         s->async_buf = scsi_get_buf(s->current_dev, 0);
297         if (s->dma_left) {
298             esp_do_dma(s);
299         } else if (s->dma_counter != 0 && s->ti_size <= 0) {
300             /* If this was the last part of a DMA transfer then the
301                completion interrupt is deferred to here.  */
302             esp_dma_done(s);
303         }
304     }
305 }
306
307 static void handle_ti(ESPState *s)
308 {
309     uint32_t dmalen, minlen;
310
311     dmalen = s->rregs[0] | (s->rregs[1] << 8);
312     if (dmalen==0) {
313       dmalen=0x10000;
314     }
315     s->dma_counter = dmalen;
316
317     if (s->do_cmd)
318         minlen = (dmalen < 32) ? dmalen : 32;
319     else if (s->ti_size < 0)
320         minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
321     else
322         minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
323     DPRINTF("Transfer Information len %d\n", minlen);
324     if (s->dma) {
325         s->dma_left = minlen;
326         s->rregs[4] &= ~STAT_TC;
327         esp_do_dma(s);
328     } else if (s->do_cmd) {
329         DPRINTF("command len %d\n", s->cmdlen);
330         s->ti_size = 0;
331         s->cmdlen = 0;
332         s->do_cmd = 0;
333         do_cmd(s, s->cmdbuf);
334         return;
335     }
336 }
337
338 static void esp_reset(void *opaque)
339 {
340     ESPState *s = opaque;
341
342     memset(s->rregs, 0, ESP_REGS);
343     memset(s->wregs, 0, ESP_REGS);
344     s->rregs[0x0e] = 0x4; // Indicate fas100a
345     s->ti_size = 0;
346     s->ti_rptr = 0;
347     s->ti_wptr = 0;
348     s->dma = 0;
349     s->do_cmd = 0;
350 }
351
352 static void parent_esp_reset(void *opaque, int irq, int level)
353 {
354     if (level)
355         esp_reset(opaque);
356 }
357
358 static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
359 {
360     ESPState *s = opaque;
361     uint32_t saddr;
362
363     saddr = (addr & ESP_MASK) >> 2;
364     DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
365     switch (saddr) {
366     case 2:
367         // FIFO
368         if (s->ti_size > 0) {
369             s->ti_size--;
370             if ((s->rregs[4] & 6) == 0) {
371                 /* Data in/out.  */
372                 fprintf(stderr, "esp: PIO data read not implemented\n");
373                 s->rregs[2] = 0;
374             } else {
375                 s->rregs[2] = s->ti_buf[s->ti_rptr++];
376             }
377             qemu_irq_raise(s->irq);
378         }
379         if (s->ti_size == 0) {
380             s->ti_rptr = 0;
381             s->ti_wptr = 0;
382         }
383         break;
384     case 5:
385         // interrupt
386         // Clear interrupt/error status bits
387         s->rregs[4] &= ~(STAT_IN | STAT_GE | STAT_PE);
388         qemu_irq_lower(s->irq);
389         break;
390     default:
391         break;
392     }
393     return s->rregs[saddr];
394 }
395
396 static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
397 {
398     ESPState *s = opaque;
399     uint32_t saddr;
400
401     saddr = (addr & ESP_MASK) >> 2;
402     DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val);
403     switch (saddr) {
404     case 0:
405     case 1:
406         s->rregs[4] &= ~STAT_TC;
407         break;
408     case 2:
409         // FIFO
410         if (s->do_cmd) {
411             s->cmdbuf[s->cmdlen++] = val & 0xff;
412         } else if ((s->rregs[4] & 6) == 0) {
413             uint8_t buf;
414             buf = val & 0xff;
415             s->ti_size--;
416             fprintf(stderr, "esp: PIO data write not implemented\n");
417         } else {
418             s->ti_size++;
419             s->ti_buf[s->ti_wptr++] = val & 0xff;
420         }
421         break;
422     case 3:
423         s->rregs[saddr] = val;
424         // Command
425         if (val & 0x80) {
426             s->dma = 1;
427             /* Reload DMA counter.  */
428             s->rregs[0] = s->wregs[0];
429             s->rregs[1] = s->wregs[1];
430         } else {
431             s->dma = 0;
432         }
433         switch(val & 0x7f) {
434         case 0:
435             DPRINTF("NOP (%2.2x)\n", val);
436             break;
437         case 1:
438             DPRINTF("Flush FIFO (%2.2x)\n", val);
439             //s->ti_size = 0;
440             s->rregs[5] = INTR_FC;
441             s->rregs[6] = 0;
442             break;
443         case 2:
444             DPRINTF("Chip reset (%2.2x)\n", val);
445             esp_reset(s);
446             break;
447         case 3:
448             DPRINTF("Bus reset (%2.2x)\n", val);
449             s->rregs[5] = INTR_RST;
450             if (!(s->wregs[8] & 0x40)) {
451                 qemu_irq_raise(s->irq);
452             }
453             break;
454         case 0x10:
455             handle_ti(s);
456             break;
457         case 0x11:
458             DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
459             write_response(s);
460             break;
461         case 0x12:
462             DPRINTF("Message Accepted (%2.2x)\n", val);
463             write_response(s);
464             s->rregs[5] = INTR_DC;
465             s->rregs[6] = 0;
466             break;
467         case 0x1a:
468             DPRINTF("Set ATN (%2.2x)\n", val);
469             break;
470         case 0x42:
471             DPRINTF("Set ATN (%2.2x)\n", val);
472             handle_satn(s);
473             break;
474         case 0x43:
475             DPRINTF("Set ATN & stop (%2.2x)\n", val);
476             handle_satn_stop(s);
477             break;
478         case 0x44:
479             DPRINTF("Enable selection (%2.2x)\n", val);
480             break;
481         default:
482             DPRINTF("Unhandled ESP command (%2.2x)\n", val);
483             break;
484         }
485         break;
486     case 4 ... 7:
487         break;
488     case 8:
489         s->rregs[saddr] = val;
490         break;
491     case 9 ... 10:
492         break;
493     case 11:
494         s->rregs[saddr] = val & 0x15;
495         break;
496     case 12 ... 15:
497         s->rregs[saddr] = val;
498         break;
499     default:
500         break;
501     }
502     s->wregs[saddr] = val;
503 }
504
505 static CPUReadMemoryFunc *esp_mem_read[3] = {
506     esp_mem_readb,
507     esp_mem_readb,
508     esp_mem_readb,
509 };
510
511 static CPUWriteMemoryFunc *esp_mem_write[3] = {
512     esp_mem_writeb,
513     esp_mem_writeb,
514     esp_mem_writeb,
515 };
516
517 static void esp_save(QEMUFile *f, void *opaque)
518 {
519     ESPState *s = opaque;
520
521     qemu_put_buffer(f, s->rregs, ESP_REGS);
522     qemu_put_buffer(f, s->wregs, ESP_REGS);
523     qemu_put_be32s(f, &s->ti_size);
524     qemu_put_be32s(f, &s->ti_rptr);
525     qemu_put_be32s(f, &s->ti_wptr);
526     qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
527     qemu_put_be32s(f, &s->sense);
528     qemu_put_be32s(f, &s->dma);
529     qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ);
530     qemu_put_be32s(f, &s->cmdlen);
531     qemu_put_be32s(f, &s->do_cmd);
532     qemu_put_be32s(f, &s->dma_left);
533     // There should be no transfers in progress, so dma_counter is not saved
534 }
535
536 static int esp_load(QEMUFile *f, void *opaque, int version_id)
537 {
538     ESPState *s = opaque;
539
540     if (version_id != 3)
541         return -EINVAL; // Cannot emulate 2
542
543     qemu_get_buffer(f, s->rregs, ESP_REGS);
544     qemu_get_buffer(f, s->wregs, ESP_REGS);
545     qemu_get_be32s(f, &s->ti_size);
546     qemu_get_be32s(f, &s->ti_rptr);
547     qemu_get_be32s(f, &s->ti_wptr);
548     qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
549     qemu_get_be32s(f, &s->sense);
550     qemu_get_be32s(f, &s->dma);
551     qemu_get_buffer(f, s->cmdbuf, TI_BUFSZ);
552     qemu_get_be32s(f, &s->cmdlen);
553     qemu_get_be32s(f, &s->do_cmd);
554     qemu_get_be32s(f, &s->dma_left);
555
556     return 0;
557 }
558
559 void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
560 {
561     ESPState *s = (ESPState *)opaque;
562
563     if (id < 0) {
564         for (id = 0; id < ESP_MAX_DEVS; id++) {
565             if (s->scsi_dev[id] == NULL)
566                 break;
567         }
568     }
569     if (id >= ESP_MAX_DEVS) {
570         DPRINTF("Bad Device ID %d\n", id);
571         return;
572     }
573     if (s->scsi_dev[id]) {
574         DPRINTF("Destroying device %d\n", id);
575         scsi_disk_destroy(s->scsi_dev[id]);
576     }
577     DPRINTF("Attaching block device %d\n", id);
578     /* Command queueing is not implemented.  */
579     s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
580 }
581
582 void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
583                void *dma_opaque, qemu_irq irq, qemu_irq *reset)
584 {
585     ESPState *s;
586     int esp_io_memory;
587
588     s = qemu_mallocz(sizeof(ESPState));
589     if (!s)
590         return NULL;
591
592     s->bd = bd;
593     s->irq = irq;
594     s->dma_opaque = dma_opaque;
595
596     esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
597     cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory);
598
599     esp_reset(s);
600
601     register_savevm("esp", espaddr, 3, esp_save, esp_load, s);
602     qemu_register_reset(esp_reset, s);
603
604     *reset = *qemu_allocate_irqs(parent_esp_reset, s, 1);
605
606     return s;
607 }