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