4 * Copyright (c) 2005-2006 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
30 #define DPRINTF(fmt, args...) \
31 do { printf("ESP: " fmt , ##args); } while (0)
32 #define pic_set_irq(irq, level) \
33 do { printf("ESP: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
35 #define DPRINTF(fmt, args...)
39 #define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1)
40 #define ESP_MAXREG 0x3f
41 #define TI_BUFSZ 1024*1024 // XXX
42 #define DMA_VER 0xa0000000
44 #define DMA_INTREN 0x10
45 #define DMA_LOADED 0x04000000
46 typedef struct ESPState ESPState
;
48 typedef int ESPDMAFunc(ESPState
*s
,
49 target_phys_addr_t phys_addr
,
53 BlockDriverState
**bd
;
54 uint8_t rregs
[ESP_MAXREG
];
55 uint8_t wregs
[ESP_MAXREG
];
57 uint32_t espdmaregs
[ESPDMA_REGS
];
59 uint32_t ti_rptr
, ti_wptr
;
61 uint8_t ti_buf
[TI_BUFSZ
];
86 /* XXX: stolen from ide.c, move to common ATAPI/SCSI library */
87 static void lba_to_msf(uint8_t *buf
, int lba
)
90 buf
[0] = (lba
/ 75) / 60;
91 buf
[1] = (lba
/ 75) % 60;
95 static inline void cpu_to_ube16(uint8_t *buf
, int val
)
101 static inline void cpu_to_ube32(uint8_t *buf
, unsigned int val
)
109 /* same toc as bochs. Return -1 if error or the toc length */
110 /* XXX: check this */
111 static int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
)
116 if (start_track
> 1 && start_track
!= 0xaa)
119 *q
++ = 1; /* first session */
120 *q
++ = 1; /* last session */
121 if (start_track
<= 1) {
122 *q
++ = 0; /* reserved */
123 *q
++ = 0x14; /* ADR, control */
124 *q
++ = 1; /* track number */
125 *q
++ = 0; /* reserved */
127 *q
++ = 0; /* reserved */
137 *q
++ = 0; /* reserved */
138 *q
++ = 0x16; /* ADR, control */
139 *q
++ = 0xaa; /* track number */
140 *q
++ = 0; /* reserved */
142 *q
++ = 0; /* reserved */
143 lba_to_msf(q
, nb_sectors
);
146 cpu_to_ube32(q
, nb_sectors
);
150 cpu_to_ube16(buf
, len
- 2);
154 /* mostly same info as PearPc */
155 static int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
,
162 *q
++ = 1; /* first session */
163 *q
++ = 1; /* last session */
165 *q
++ = 1; /* session number */
166 *q
++ = 0x14; /* data track */
167 *q
++ = 0; /* track number */
168 *q
++ = 0xa0; /* lead-in */
171 *q
++ = 0; /* frame */
173 *q
++ = 1; /* first track */
174 *q
++ = 0x00; /* disk type */
177 *q
++ = 1; /* session number */
178 *q
++ = 0x14; /* data track */
179 *q
++ = 0; /* track number */
183 *q
++ = 0; /* frame */
185 *q
++ = 1; /* last track */
189 *q
++ = 1; /* session number */
190 *q
++ = 0x14; /* data track */
191 *q
++ = 0; /* track number */
192 *q
++ = 0xa2; /* lead-out */
195 *q
++ = 0; /* frame */
197 *q
++ = 0; /* reserved */
198 lba_to_msf(q
, nb_sectors
);
201 cpu_to_ube32(q
, nb_sectors
);
205 *q
++ = 1; /* session number */
206 *q
++ = 0x14; /* ADR, control */
207 *q
++ = 0; /* track number */
208 *q
++ = 1; /* point */
211 *q
++ = 0; /* frame */
224 cpu_to_ube16(buf
, len
- 2);
228 static int esp_write_dma_cb(ESPState
*s
,
229 target_phys_addr_t phys_addr
,
232 DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n",
233 s
->offset
, s
->len
, s
->ti_size
, transfer_size1
);
234 bdrv_write(s
->bd
[s
->target
], s
->offset
, s
->ti_buf
, s
->len
);
241 static void handle_satn(ESPState
*s
)
244 uint32_t dmaptr
, dmalen
;
249 dmalen
= s
->wregs
[0] | (s
->wregs
[1] << 8);
250 target
= s
->wregs
[4] & 7;
251 DPRINTF("Select with ATN len %d target %d\n", dmalen
, target
);
253 dmaptr
= iommu_translate(s
->espdmaregs
[1]);
254 DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s
->espdmaregs
[0] & 0x100? 'w': 'r', dmaptr
);
255 cpu_physical_memory_read(dmaptr
, buf
, dmalen
);
258 memcpy(&buf
[1], s
->ti_buf
, dmalen
);
261 for (i
= 0; i
< dmalen
; i
++) {
262 DPRINTF("Command %2.2x\n", buf
[i
]);
269 if (target
>= 4 || !s
->bd
[target
]) { // No such drive
270 s
->rregs
[4] = STAT_IN
;
271 s
->rregs
[5] = INTR_DC
;
273 s
->espdmaregs
[0] |= DMA_INTR
;
274 pic_set_irq(s
->irq
, 1);
279 DPRINTF("Test Unit Ready (len %d)\n", buf
[5]);
282 DPRINTF("Inquiry (len %d)\n", buf
[5]);
283 memset(s
->ti_buf
, 0, 36);
284 if (bdrv_get_type_hint(s
->bd
[target
]) == BDRV_TYPE_CDROM
) {
286 memcpy(&s
->ti_buf
[16], "QEMU CDROM ", 16);
289 memcpy(&s
->ti_buf
[16], "QEMU HARDDISK ", 16);
291 memcpy(&s
->ti_buf
[8], "QEMU ", 8);
299 DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf
[3], buf
[5]);
302 DPRINTF("Read Capacity (len %d)\n", buf
[5]);
303 memset(s
->ti_buf
, 0, 8);
304 bdrv_get_geometry(s
->bd
[target
], &nb_sectors
);
305 s
->ti_buf
[0] = (nb_sectors
>> 24) & 0xff;
306 s
->ti_buf
[1] = (nb_sectors
>> 16) & 0xff;
307 s
->ti_buf
[2] = (nb_sectors
>> 8) & 0xff;
308 s
->ti_buf
[3] = nb_sectors
& 0xff;
311 if (bdrv_get_type_hint(s
->bd
[target
]) == BDRV_TYPE_CDROM
)
312 s
->ti_buf
[6] = 8; // sector size 2048
314 s
->ti_buf
[6] = 2; // sector size 512
323 if (bdrv_get_type_hint(s
->bd
[target
]) == BDRV_TYPE_CDROM
) {
324 offset
= ((buf
[3] << 24) | (buf
[4] << 16) | (buf
[5] << 8) | buf
[6]) * 4;
325 len
= ((buf
[8] << 8) | buf
[9]) * 4;
326 s
->ti_size
= len
* 2048;
328 offset
= (buf
[3] << 24) | (buf
[4] << 16) | (buf
[5] << 8) | buf
[6];
329 len
= (buf
[8] << 8) | buf
[9];
330 s
->ti_size
= len
* 512;
332 DPRINTF("Read (10) (offset %lld len %lld)\n", offset
, len
);
333 if (s
->ti_size
> TI_BUFSZ
) {
334 DPRINTF("size too large %d\n", s
->ti_size
);
336 bdrv_read(s
->bd
[target
], offset
, s
->ti_buf
, len
);
337 // XXX error handling
345 if (bdrv_get_type_hint(s
->bd
[target
]) == BDRV_TYPE_CDROM
) {
346 offset
= ((buf
[3] << 24) | (buf
[4] << 16) | (buf
[5] << 8) | buf
[6]) * 4;
347 len
= ((buf
[8] << 8) | buf
[9]) * 4;
348 s
->ti_size
= len
* 2048;
350 offset
= (buf
[3] << 24) | (buf
[4] << 16) | (buf
[5] << 8) | buf
[6];
351 len
= (buf
[8] << 8) | buf
[9];
352 s
->ti_size
= len
* 512;
354 DPRINTF("Write (10) (offset %lld len %lld)\n", offset
, len
);
355 if (s
->ti_size
> TI_BUFSZ
) {
356 DPRINTF("size too large %d\n", s
->ti_size
);
358 s
->dma_cb
= esp_write_dma_cb
;
362 // XXX error handling
368 int start_track
, format
, msf
, len
;
371 format
= buf
[3] & 0xf;
372 start_track
= buf
[7];
373 bdrv_get_geometry(s
->bd
[target
], &nb_sectors
);
374 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
377 len
= cdrom_read_toc(nb_sectors
, buf
, msf
, start_track
);
383 /* multi session : only a single session defined */
391 len
= cdrom_read_toc_raw(nb_sectors
, buf
, msf
, start_track
);
398 DPRINTF("Read TOC error\n");
399 // XXX error handling
406 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[1]);
409 s
->rregs
[4] = STAT_IN
| STAT_TC
| STAT_DI
;
410 s
->rregs
[5] = INTR_BS
| INTR_FC
;
411 s
->rregs
[6] = SEQ_CD
;
412 s
->espdmaregs
[0] |= DMA_INTR
;
413 pic_set_irq(s
->irq
, 1);
416 static void dma_write(ESPState
*s
, const uint8_t *buf
, uint32_t len
)
418 uint32_t dmaptr
, dmalen
;
420 dmalen
= s
->wregs
[0] | (s
->wregs
[1] << 8);
421 DPRINTF("Transfer status len %d\n", dmalen
);
423 dmaptr
= iommu_translate(s
->espdmaregs
[1]);
424 DPRINTF("DMA Direction: %c\n", s
->espdmaregs
[0] & 0x100? 'w': 'r');
425 cpu_physical_memory_write(dmaptr
, buf
, len
);
426 s
->rregs
[4] = STAT_IN
| STAT_TC
| STAT_ST
;
427 s
->rregs
[5] = INTR_BS
| INTR_FC
;
428 s
->rregs
[6] = SEQ_CD
;
430 memcpy(s
->ti_buf
, buf
, len
);
434 s
->rregs
[7] = dmalen
;
436 s
->espdmaregs
[0] |= DMA_INTR
;
437 pic_set_irq(s
->irq
, 1);
441 static const uint8_t okbuf
[] = {0, 0};
443 static void handle_ti(ESPState
*s
)
445 uint32_t dmaptr
, dmalen
;
448 dmalen
= s
->wregs
[0] | (s
->wregs
[1] << 8);
449 DPRINTF("Transfer Information len %d\n", dmalen
);
451 dmaptr
= iommu_translate(s
->espdmaregs
[1]);
452 DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s
->espdmaregs
[0] & 0x100? 'w': 'r', dmaptr
);
453 for (i
= 0; i
< s
->ti_size
; i
++) {
454 dmaptr
= iommu_translate(s
->espdmaregs
[1] + i
);
456 cpu_physical_memory_write(dmaptr
, &s
->ti_buf
[i
], 1);
458 cpu_physical_memory_read(dmaptr
, &s
->ti_buf
[i
], 1);
461 s
->dma_cb(s
, s
->espdmaregs
[1], dmalen
);
464 s
->rregs
[4] = STAT_IN
| STAT_TC
| STAT_ST
;
465 s
->rregs
[5] = INTR_BS
;
467 s
->espdmaregs
[0] |= DMA_INTR
;
472 s
->rregs
[7] = dmalen
;
474 pic_set_irq(s
->irq
, 1);
477 static void esp_reset(void *opaque
)
479 ESPState
*s
= opaque
;
480 memset(s
->rregs
, 0, ESP_MAXREG
);
481 memset(s
->wregs
, 0, ESP_MAXREG
);
482 s
->rregs
[0x0e] = 0x4; // Indicate fas100a
483 memset(s
->espdmaregs
, 0, ESPDMA_REGS
* 4);
492 static uint32_t esp_mem_readb(void *opaque
, target_phys_addr_t addr
)
494 ESPState
*s
= opaque
;
497 saddr
= (addr
& ESP_MAXREG
) >> 2;
498 DPRINTF("read reg[%d]: 0x%2.2x\n", saddr
, s
->rregs
[saddr
]);
502 if (s
->ti_size
> 0) {
504 s
->rregs
[saddr
] = s
->ti_buf
[s
->ti_rptr
++];
505 pic_set_irq(s
->irq
, 1);
507 if (s
->ti_size
== 0) {
514 // Clear status bits except TC
515 s
->rregs
[4] &= STAT_TC
;
516 pic_set_irq(s
->irq
, 0);
517 s
->espdmaregs
[0] &= ~DMA_INTR
;
522 return s
->rregs
[saddr
];
525 static void esp_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
527 ESPState
*s
= opaque
;
530 saddr
= (addr
& ESP_MAXREG
) >> 2;
531 DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr
, s
->wregs
[saddr
], val
);
535 s
->rregs
[saddr
] = val
;
540 s
->ti_buf
[s
->ti_wptr
++] = val
& 0xff;
543 s
->rregs
[saddr
] = val
;
552 DPRINTF("NOP (%2.2x)\n", val
);
555 DPRINTF("Flush FIFO (%2.2x)\n", val
);
557 s
->rregs
[5] = INTR_FC
;
561 DPRINTF("Chip reset (%2.2x)\n", val
);
565 DPRINTF("Bus reset (%2.2x)\n", val
);
566 s
->rregs
[5] = INTR_RST
;
567 if (!(s
->wregs
[8] & 0x40)) {
568 s
->espdmaregs
[0] |= DMA_INTR
;
569 pic_set_irq(s
->irq
, 1);
576 DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val
);
577 dma_write(s
, okbuf
, 2);
580 DPRINTF("Message Accepted (%2.2x)\n", val
);
581 dma_write(s
, okbuf
, 2);
582 s
->rregs
[5] = INTR_DC
;
586 DPRINTF("Set ATN (%2.2x)\n", val
);
592 DPRINTF("Set ATN & stop (%2.2x)\n", val
);
596 DPRINTF("Unhandled ESP command (%2.2x)\n", val
);
603 s
->rregs
[saddr
] = val
;
608 s
->rregs
[saddr
] = val
& 0x15;
611 s
->rregs
[saddr
] = val
;
616 s
->wregs
[saddr
] = val
;
619 static CPUReadMemoryFunc
*esp_mem_read
[3] = {
625 static CPUWriteMemoryFunc
*esp_mem_write
[3] = {
631 static uint32_t espdma_mem_readl(void *opaque
, target_phys_addr_t addr
)
633 ESPState
*s
= opaque
;
636 saddr
= (addr
& ESPDMA_MAXADDR
) >> 2;
637 DPRINTF("read dmareg[%d]: 0x%8.8x\n", saddr
, s
->espdmaregs
[saddr
]);
639 return s
->espdmaregs
[saddr
];
642 static void espdma_mem_writel(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
644 ESPState
*s
= opaque
;
647 saddr
= (addr
& ESPDMA_MAXADDR
) >> 2;
648 DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr
, s
->espdmaregs
[saddr
], val
);
651 if (!(val
& DMA_INTREN
))
652 pic_set_irq(s
->irq
, 0);
655 } else if (val
& 0x40) {
663 s
->espdmaregs
[0] = DMA_LOADED
;
668 s
->espdmaregs
[saddr
] = val
;
671 static CPUReadMemoryFunc
*espdma_mem_read
[3] = {
677 static CPUWriteMemoryFunc
*espdma_mem_write
[3] = {
683 static void esp_save(QEMUFile
*f
, void *opaque
)
685 ESPState
*s
= opaque
;
688 qemu_put_buffer(f
, s
->rregs
, ESP_MAXREG
);
689 qemu_put_buffer(f
, s
->wregs
, ESP_MAXREG
);
690 qemu_put_be32s(f
, &s
->irq
);
691 for (i
= 0; i
< ESPDMA_REGS
; i
++)
692 qemu_put_be32s(f
, &s
->espdmaregs
[i
]);
693 qemu_put_be32s(f
, &s
->ti_size
);
694 qemu_put_be32s(f
, &s
->ti_rptr
);
695 qemu_put_be32s(f
, &s
->ti_wptr
);
696 qemu_put_be32s(f
, &s
->ti_dir
);
697 qemu_put_buffer(f
, s
->ti_buf
, TI_BUFSZ
);
698 qemu_put_be32s(f
, &s
->dma
);
701 static int esp_load(QEMUFile
*f
, void *opaque
, int version_id
)
703 ESPState
*s
= opaque
;
709 qemu_get_buffer(f
, s
->rregs
, ESP_MAXREG
);
710 qemu_get_buffer(f
, s
->wregs
, ESP_MAXREG
);
711 qemu_get_be32s(f
, &s
->irq
);
712 for (i
= 0; i
< ESPDMA_REGS
; i
++)
713 qemu_get_be32s(f
, &s
->espdmaregs
[i
]);
714 qemu_get_be32s(f
, &s
->ti_size
);
715 qemu_get_be32s(f
, &s
->ti_rptr
);
716 qemu_get_be32s(f
, &s
->ti_wptr
);
717 qemu_get_be32s(f
, &s
->ti_dir
);
718 qemu_get_buffer(f
, s
->ti_buf
, TI_BUFSZ
);
719 qemu_get_be32s(f
, &s
->dma
);
724 void esp_init(BlockDriverState
**bd
, int irq
, uint32_t espaddr
, uint32_t espdaddr
)
727 int esp_io_memory
, espdma_io_memory
;
729 s
= qemu_mallocz(sizeof(ESPState
));
736 esp_io_memory
= cpu_register_io_memory(0, esp_mem_read
, esp_mem_write
, s
);
737 cpu_register_physical_memory(espaddr
, ESP_MAXREG
*4, esp_io_memory
);
739 espdma_io_memory
= cpu_register_io_memory(0, espdma_mem_read
, espdma_mem_write
, s
);
740 cpu_register_physical_memory(espdaddr
, 16, espdma_io_memory
);
744 register_savevm("esp", espaddr
, 1, esp_save
, esp_load
, s
);
745 qemu_register_reset(esp_reset
, s
);