Commit e3007e6677fd5723dac5a10033319aa0f8dfaf64

Authored by aurel32
1 parent 28ce5ce6

PowerPC: IDE DB-DMA support

This patches allows powermac IDE interface to use DB-DMA.
This implementation uses only synchronous I/O.

Signed-off-by: Laurent Vivier <Laurent@lvivier.info>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6489 c046a42c-6fe2-441c-8c8c-71466251a162
hw/ide.c
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include "qemu-timer.h" 31 #include "qemu-timer.h"
32 #include "sysemu.h" 32 #include "sysemu.h"
33 #include "ppc_mac.h" 33 #include "ppc_mac.h"
  34 +#include "mac_dbdma.h"
34 #include "sh.h" 35 #include "sh.h"
35 36
36 /* debug IDE devices */ 37 /* debug IDE devices */
@@ -437,6 +438,8 @@ typedef struct IDEState { @@ -437,6 +438,8 @@ typedef struct IDEState {
437 uint32_t mdata_size; 438 uint32_t mdata_size;
438 uint8_t *mdata_storage; 439 uint8_t *mdata_storage;
439 int media_changed; 440 int media_changed;
  441 + /* for pmac */
  442 + int is_read;
440 } IDEState; 443 } IDEState;
441 444
442 /* XXX: DVDs that could fit on a CD will be reported as a CD */ 445 /* XXX: DVDs that could fit on a CD will be reported as a CD */
@@ -1094,6 +1097,7 @@ static void ide_sector_read_dma(IDEState *s) @@ -1094,6 +1097,7 @@ static void ide_sector_read_dma(IDEState *s)
1094 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; 1097 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1095 s->io_buffer_index = 0; 1098 s->io_buffer_index = 0;
1096 s->io_buffer_size = 0; 1099 s->io_buffer_size = 0;
  1100 + s->is_read = 1;
1097 ide_dma_start(s, ide_read_dma_cb); 1101 ide_dma_start(s, ide_read_dma_cb);
1098 } 1102 }
1099 1103
@@ -1222,6 +1226,7 @@ static void ide_sector_write_dma(IDEState *s) @@ -1222,6 +1226,7 @@ static void ide_sector_write_dma(IDEState *s)
1222 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; 1226 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1223 s->io_buffer_index = 0; 1227 s->io_buffer_index = 0;
1224 s->io_buffer_size = 0; 1228 s->io_buffer_size = 0;
  1229 + s->is_read = 0;
1225 ide_dma_start(s, ide_write_dma_cb); 1230 ide_dma_start(s, ide_write_dma_cb);
1226 } 1231 }
1227 1232
@@ -3473,21 +3478,130 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -3473,21 +3478,130 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3473 register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d); 3478 register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
3474 } 3479 }
3475 3480
  3481 +#if defined(TARGET_PPC)
3476 /***********************************************************/ 3482 /***********************************************************/
3477 /* MacIO based PowerPC IDE */ 3483 /* MacIO based PowerPC IDE */
3478 3484
  3485 +typedef struct MACIOIDEState {
  3486 + IDEState ide_if[2];
  3487 + void *dbdma;
  3488 + int stream_index;
  3489 +} MACIOIDEState;
  3490 +
  3491 +static int pmac_atapi_read(DBDMA_transfer *info, DBDMA_transfer_cb cb)
  3492 +{
  3493 + MACIOIDEState *m = info->opaque;
  3494 + IDEState *s = m->ide_if->cur_drive;
  3495 + int ret;
  3496 +
  3497 + if (s->lba == -1)
  3498 + return 0;
  3499 +
  3500 + info->buf_pos = 0;
  3501 +
  3502 + while (info->buf_pos < info->len && s->packet_transfer_size > 0) {
  3503 +
  3504 + ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
  3505 + if (ret < 0) {
  3506 + ide_transfer_stop(s);
  3507 + ide_atapi_io_error(s, ret);
  3508 + return info->buf_pos;
  3509 + }
  3510 +
  3511 + info->buf = s->io_buffer + m->stream_index;
  3512 +
  3513 + info->buf_len = s->cd_sector_size;
  3514 + if (info->buf_pos + info->buf_len > info->len)
  3515 + info->buf_len = info->len - info->buf_pos;
  3516 +
  3517 + cb(info);
  3518 +
  3519 + /* db-dma can ask for 512 bytes whereas block size is 2048... */
  3520 +
  3521 + m->stream_index += info->buf_len;
  3522 + s->lba += m->stream_index / s->cd_sector_size;
  3523 + m->stream_index %= s->cd_sector_size;
  3524 +
  3525 + info->buf_pos += info->buf_len;
  3526 + s->packet_transfer_size -= info->buf_len;
  3527 + }
  3528 + if (s->packet_transfer_size <= 0) {
  3529 + s->status = READY_STAT | SEEK_STAT;
  3530 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO
  3531 + | ATAPI_INT_REASON_CD;
  3532 + ide_set_irq(s);
  3533 + }
  3534 +
  3535 + return info->buf_pos;
  3536 +}
  3537 +
  3538 +static int pmac_ide_transfer(DBDMA_transfer *info,
  3539 + DBDMA_transfer_cb cb)
  3540 +{
  3541 + MACIOIDEState *m = info->opaque;
  3542 + IDEState *s = m->ide_if->cur_drive;
  3543 + int64_t sector_num;
  3544 + int ret, n;
  3545 +
  3546 + if (s->is_cdrom)
  3547 + return pmac_atapi_read(info, cb);
  3548 +
  3549 + info->buf = s->io_buffer;
  3550 + info->buf_pos = 0;
  3551 + while (info->buf_pos < info->len && s->nsector > 0) {
  3552 +
  3553 + sector_num = ide_get_sector(s);
  3554 +
  3555 + n = s->nsector;
  3556 + if (n > IDE_DMA_BUF_SECTORS)
  3557 + n = IDE_DMA_BUF_SECTORS;
  3558 +
  3559 + info->buf_len = n << 9;
  3560 + if (info->buf_pos + info->buf_len > info->len)
  3561 + info->buf_len = info->len - info->buf_pos;
  3562 + n = info->buf_len >> 9;
  3563 +
  3564 + if (s->is_read) {
  3565 + ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
  3566 + if (ret == 0)
  3567 + cb(info);
  3568 + } else {
  3569 + cb(info);
  3570 + ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
  3571 + }
  3572 +
  3573 + if (ret != 0) {
  3574 + ide_rw_error(s);
  3575 + return info->buf_pos;
  3576 + }
  3577 +
  3578 + info->buf_pos += n << 9;
  3579 + ide_set_sector(s, sector_num + n);
  3580 + s->nsector -= n;
  3581 + }
  3582 +
  3583 + if (s->nsector <= 0) {
  3584 + s->status = READY_STAT | SEEK_STAT;
  3585 + ide_set_irq(s);
  3586 + }
  3587 +
  3588 + return info->buf_pos;
  3589 +}
  3590 +
3479 /* PowerMac IDE memory IO */ 3591 /* PowerMac IDE memory IO */
3480 static void pmac_ide_writeb (void *opaque, 3592 static void pmac_ide_writeb (void *opaque,
3481 target_phys_addr_t addr, uint32_t val) 3593 target_phys_addr_t addr, uint32_t val)
3482 { 3594 {
  3595 + MACIOIDEState *d = opaque;
  3596 +
3483 addr = (addr & 0xFFF) >> 4; 3597 addr = (addr & 0xFFF) >> 4;
3484 switch (addr) { 3598 switch (addr) {
3485 case 1 ... 7: 3599 case 1 ... 7:
3486 - ide_ioport_write(opaque, addr, val); 3600 + ide_ioport_write(d->ide_if, addr, val);
3487 break; 3601 break;
3488 case 8: 3602 case 8:
3489 case 22: 3603 case 22:
3490 - ide_cmd_write(opaque, 0, val); 3604 + ide_cmd_write(d->ide_if, 0, val);
3491 break; 3605 break;
3492 default: 3606 default:
3493 break; 3607 break;
@@ -3497,15 +3611,16 @@ static void pmac_ide_writeb (void *opaque, @@ -3497,15 +3611,16 @@ static void pmac_ide_writeb (void *opaque,
3497 static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr) 3611 static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3498 { 3612 {
3499 uint8_t retval; 3613 uint8_t retval;
  3614 + MACIOIDEState *d = opaque;
3500 3615
3501 addr = (addr & 0xFFF) >> 4; 3616 addr = (addr & 0xFFF) >> 4;
3502 switch (addr) { 3617 switch (addr) {
3503 case 1 ... 7: 3618 case 1 ... 7:
3504 - retval = ide_ioport_read(opaque, addr); 3619 + retval = ide_ioport_read(d->ide_if, addr);
3505 break; 3620 break;
3506 case 8: 3621 case 8:
3507 case 22: 3622 case 22:
3508 - retval = ide_status_read(opaque, 0); 3623 + retval = ide_status_read(d->ide_if, 0);
3509 break; 3624 break;
3510 default: 3625 default:
3511 retval = 0xFF; 3626 retval = 0xFF;
@@ -3517,22 +3632,25 @@ static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr) @@ -3517,22 +3632,25 @@ static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3517 static void pmac_ide_writew (void *opaque, 3632 static void pmac_ide_writew (void *opaque,
3518 target_phys_addr_t addr, uint32_t val) 3633 target_phys_addr_t addr, uint32_t val)
3519 { 3634 {
  3635 + MACIOIDEState *d = opaque;
  3636 +
3520 addr = (addr & 0xFFF) >> 4; 3637 addr = (addr & 0xFFF) >> 4;
3521 #ifdef TARGET_WORDS_BIGENDIAN 3638 #ifdef TARGET_WORDS_BIGENDIAN
3522 val = bswap16(val); 3639 val = bswap16(val);
3523 #endif 3640 #endif
3524 if (addr == 0) { 3641 if (addr == 0) {
3525 - ide_data_writew(opaque, 0, val); 3642 + ide_data_writew(d->ide_if, 0, val);
3526 } 3643 }
3527 } 3644 }
3528 3645
3529 static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr) 3646 static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3530 { 3647 {
3531 uint16_t retval; 3648 uint16_t retval;
  3649 + MACIOIDEState *d = opaque;
3532 3650
3533 addr = (addr & 0xFFF) >> 4; 3651 addr = (addr & 0xFFF) >> 4;
3534 if (addr == 0) { 3652 if (addr == 0) {
3535 - retval = ide_data_readw(opaque, 0); 3653 + retval = ide_data_readw(d->ide_if, 0);
3536 } else { 3654 } else {
3537 retval = 0xFFFF; 3655 retval = 0xFFFF;
3538 } 3656 }
@@ -3545,22 +3663,25 @@ static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr) @@ -3545,22 +3663,25 @@ static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3545 static void pmac_ide_writel (void *opaque, 3663 static void pmac_ide_writel (void *opaque,
3546 target_phys_addr_t addr, uint32_t val) 3664 target_phys_addr_t addr, uint32_t val)
3547 { 3665 {
  3666 + MACIOIDEState *d = opaque;
  3667 +
3548 addr = (addr & 0xFFF) >> 4; 3668 addr = (addr & 0xFFF) >> 4;
3549 #ifdef TARGET_WORDS_BIGENDIAN 3669 #ifdef TARGET_WORDS_BIGENDIAN
3550 val = bswap32(val); 3670 val = bswap32(val);
3551 #endif 3671 #endif
3552 if (addr == 0) { 3672 if (addr == 0) {
3553 - ide_data_writel(opaque, 0, val); 3673 + ide_data_writel(d->ide_if, 0, val);
3554 } 3674 }
3555 } 3675 }
3556 3676
3557 static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr) 3677 static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
3558 { 3678 {
3559 uint32_t retval; 3679 uint32_t retval;
  3680 + MACIOIDEState *d = opaque;
3560 3681
3561 addr = (addr & 0xFFF) >> 4; 3682 addr = (addr & 0xFFF) >> 4;
3562 if (addr == 0) { 3683 if (addr == 0) {
3563 - retval = ide_data_readl(opaque, 0); 3684 + retval = ide_data_readl(d->ide_if, 0);
3564 } else { 3685 } else {
3565 retval = 0xFFFFFFFF; 3686 retval = 0xFFFFFFFF;
3566 } 3687 }
@@ -3584,7 +3705,8 @@ static CPUReadMemoryFunc *pmac_ide_read[] = { @@ -3584,7 +3705,8 @@ static CPUReadMemoryFunc *pmac_ide_read[] = {
3584 3705
3585 static void pmac_ide_save(QEMUFile *f, void *opaque) 3706 static void pmac_ide_save(QEMUFile *f, void *opaque)
3586 { 3707 {
3587 - IDEState *s = (IDEState *)opaque; 3708 + MACIOIDEState *d = opaque;
  3709 + IDEState *s = d->ide_if;
3588 uint8_t drive1_selected; 3710 uint8_t drive1_selected;
3589 unsigned int i; 3711 unsigned int i;
3590 3712
@@ -3601,7 +3723,8 @@ static void pmac_ide_save(QEMUFile *f, void *opaque) @@ -3601,7 +3723,8 @@ static void pmac_ide_save(QEMUFile *f, void *opaque)
3601 3723
3602 static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id) 3724 static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id)
3603 { 3725 {
3604 - IDEState *s = (IDEState *)opaque; 3726 + MACIOIDEState *d = opaque;
  3727 + IDEState *s = d->ide_if;
3605 uint8_t drive1_selected; 3728 uint8_t drive1_selected;
3606 unsigned int i; 3729 unsigned int i;
3607 3730
@@ -3622,7 +3745,8 @@ static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id) @@ -3622,7 +3745,8 @@ static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id)
3622 3745
3623 static void pmac_ide_reset(void *opaque) 3746 static void pmac_ide_reset(void *opaque)
3624 { 3747 {
3625 - IDEState *s = (IDEState *)opaque; 3748 + MACIOIDEState *d = opaque;
  3749 + IDEState *s = d->ide_if;
3626 3750
3627 ide_reset(&s[0]); 3751 ide_reset(&s[0]);
3628 ide_reset(&s[1]); 3752 ide_reset(&s[1]);
@@ -3631,21 +3755,29 @@ static void pmac_ide_reset(void *opaque) @@ -3631,21 +3755,29 @@ static void pmac_ide_reset(void *opaque)
3631 /* hd_table must contain 4 block drivers */ 3755 /* hd_table must contain 4 block drivers */
3632 /* PowerMac uses memory mapped registers, not I/O. Return the memory 3756 /* PowerMac uses memory mapped registers, not I/O. Return the memory
3633 I/O index to access the ide. */ 3757 I/O index to access the ide. */
3634 -int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq) 3758 +int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq,
  3759 + void *dbdma, int channel, qemu_irq dma_irq)
3635 { 3760 {
3636 - IDEState *ide_if; 3761 + MACIOIDEState *d;
3637 int pmac_ide_memory; 3762 int pmac_ide_memory;
3638 3763
3639 - ide_if = qemu_mallocz(sizeof(IDEState) * 2);  
3640 - ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq); 3764 + d = qemu_mallocz(sizeof(MACIOIDEState));
  3765 + ide_init2(d->ide_if, hd_table[0], hd_table[1], irq);
  3766 +
  3767 + if (dbdma) {
  3768 + d->dbdma = dbdma;
  3769 + DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d);
  3770 + }
3641 3771
3642 pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, 3772 pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
3643 - pmac_ide_write, &ide_if[0]);  
3644 - register_savevm("ide", 0, 1, pmac_ide_save, pmac_ide_load, &ide_if[0]);  
3645 - qemu_register_reset(pmac_ide_reset, &ide_if[0]);  
3646 - pmac_ide_reset(&ide_if[0]); 3773 + pmac_ide_write, d);
  3774 + register_savevm("ide", 0, 1, pmac_ide_save, pmac_ide_load, d);
  3775 + qemu_register_reset(pmac_ide_reset, d);
  3776 + pmac_ide_reset(d);
  3777 +
3647 return pmac_ide_memory; 3778 return pmac_ide_memory;
3648 } 3779 }
  3780 +#endif /* TARGET_PPC */
3649 3781
3650 /***********************************************************/ 3782 /***********************************************************/
3651 /* MMIO based ide port 3783 /* MMIO based ide port
hw/ppc_chrp.c
@@ -284,8 +284,8 @@ static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size, @@ -284,8 +284,8 @@ static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size,
284 } 284 }
285 dbdma = DBDMA_init(&dbdma_mem_index); 285 dbdma = DBDMA_init(&dbdma_mem_index);
286 #if 1 286 #if 1
287 - ide_mem_index[0] = pmac_ide_init(&hd[0], pic[0x13]);  
288 - ide_mem_index[1] = pmac_ide_init(&hd[2], pic[0x14]); 287 + ide_mem_index[0] = pmac_ide_init(&hd[0], pic[0x13], dbdma, 0x14, pic[0x01]);
  288 + ide_mem_index[1] = pmac_ide_init(&hd[2], pic[0x14], dbdma, 0x16, pic[0x02]);
289 #else 289 #else
290 pci_cmd646_ide_init(pci_bus, &hd[0], 0); 290 pci_cmd646_ide_init(pci_bus, &hd[0], 0);
291 #endif 291 #endif
hw/ppc_mac.h
@@ -48,7 +48,8 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, @@ -48,7 +48,8 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
48 int nb_ide, int *ide_mem_index, int escc_mem_index); 48 int nb_ide, int *ide_mem_index, int escc_mem_index);
49 49
50 /* NewWorld PowerMac IDE */ 50 /* NewWorld PowerMac IDE */
51 -int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq); 51 +int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq,
  52 + void *dbdma, int channel, qemu_irq dma_irq);
52 53
53 /* Heathrow PIC */ 54 /* Heathrow PIC */
54 qemu_irq *heathrow_pic_init(int *pmem_index, 55 qemu_irq *heathrow_pic_init(int *pmem_index,
hw/ppc_oldworld.c
@@ -349,7 +349,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, int vga_ram_size, @@ -349,7 +349,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, int vga_ram_size,
349 dbdma = DBDMA_init(&dbdma_mem_index); 349 dbdma = DBDMA_init(&dbdma_mem_index);
350 350
351 ide_mem_index[0] = -1; 351 ide_mem_index[0] = -1;
352 - ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D]); 352 + ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
353 353
354 /* cuda also initialize ADB */ 354 /* cuda also initialize ADB */
355 cuda_init(&cuda_mem_index, pic[0x12]); 355 cuda_init(&cuda_mem_index, pic[0x12]);