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