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 31 #include "qemu-timer.h"
32 32 #include "sysemu.h"
33 33 #include "ppc_mac.h"
  34 +#include "mac_dbdma.h"
34 35 #include "sh.h"
35 36  
36 37 /* debug IDE devices */
... ... @@ -437,6 +438,8 @@ typedef struct IDEState {
437 438 uint32_t mdata_size;
438 439 uint8_t *mdata_storage;
439 440 int media_changed;
  441 + /* for pmac */
  442 + int is_read;
440 443 } IDEState;
441 444  
442 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 1097 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1095 1098 s->io_buffer_index = 0;
1096 1099 s->io_buffer_size = 0;
  1100 + s->is_read = 1;
1097 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 1226 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1223 1227 s->io_buffer_index = 0;
1224 1228 s->io_buffer_size = 0;
  1229 + s->is_read = 0;
1225 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 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 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 3591 /* PowerMac IDE memory IO */
3480 3592 static void pmac_ide_writeb (void *opaque,
3481 3593 target_phys_addr_t addr, uint32_t val)
3482 3594 {
  3595 + MACIOIDEState *d = opaque;
  3596 +
3483 3597 addr = (addr & 0xFFF) >> 4;
3484 3598 switch (addr) {
3485 3599 case 1 ... 7:
3486   - ide_ioport_write(opaque, addr, val);
  3600 + ide_ioport_write(d->ide_if, addr, val);
3487 3601 break;
3488 3602 case 8:
3489 3603 case 22:
3490   - ide_cmd_write(opaque, 0, val);
  3604 + ide_cmd_write(d->ide_if, 0, val);
3491 3605 break;
3492 3606 default:
3493 3607 break;
... ... @@ -3497,15 +3611,16 @@ static void pmac_ide_writeb (void *opaque,
3497 3611 static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3498 3612 {
3499 3613 uint8_t retval;
  3614 + MACIOIDEState *d = opaque;
3500 3615  
3501 3616 addr = (addr & 0xFFF) >> 4;
3502 3617 switch (addr) {
3503 3618 case 1 ... 7:
3504   - retval = ide_ioport_read(opaque, addr);
  3619 + retval = ide_ioport_read(d->ide_if, addr);
3505 3620 break;
3506 3621 case 8:
3507 3622 case 22:
3508   - retval = ide_status_read(opaque, 0);
  3623 + retval = ide_status_read(d->ide_if, 0);
3509 3624 break;
3510 3625 default:
3511 3626 retval = 0xFF;
... ... @@ -3517,22 +3632,25 @@ static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3517 3632 static void pmac_ide_writew (void *opaque,
3518 3633 target_phys_addr_t addr, uint32_t val)
3519 3634 {
  3635 + MACIOIDEState *d = opaque;
  3636 +
3520 3637 addr = (addr & 0xFFF) >> 4;
3521 3638 #ifdef TARGET_WORDS_BIGENDIAN
3522 3639 val = bswap16(val);
3523 3640 #endif
3524 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 3646 static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3530 3647 {
3531 3648 uint16_t retval;
  3649 + MACIOIDEState *d = opaque;
3532 3650  
3533 3651 addr = (addr & 0xFFF) >> 4;
3534 3652 if (addr == 0) {
3535   - retval = ide_data_readw(opaque, 0);
  3653 + retval = ide_data_readw(d->ide_if, 0);
3536 3654 } else {
3537 3655 retval = 0xFFFF;
3538 3656 }
... ... @@ -3545,22 +3663,25 @@ static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3545 3663 static void pmac_ide_writel (void *opaque,
3546 3664 target_phys_addr_t addr, uint32_t val)
3547 3665 {
  3666 + MACIOIDEState *d = opaque;
  3667 +
3548 3668 addr = (addr & 0xFFF) >> 4;
3549 3669 #ifdef TARGET_WORDS_BIGENDIAN
3550 3670 val = bswap32(val);
3551 3671 #endif
3552 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 3677 static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
3558 3678 {
3559 3679 uint32_t retval;
  3680 + MACIOIDEState *d = opaque;
3560 3681  
3561 3682 addr = (addr & 0xFFF) >> 4;
3562 3683 if (addr == 0) {
3563   - retval = ide_data_readl(opaque, 0);
  3684 + retval = ide_data_readl(d->ide_if, 0);
3564 3685 } else {
3565 3686 retval = 0xFFFFFFFF;
3566 3687 }
... ... @@ -3584,7 +3705,8 @@ static CPUReadMemoryFunc *pmac_ide_read[] = {
3584 3705  
3585 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 3710 uint8_t drive1_selected;
3589 3711 unsigned int i;
3590 3712  
... ... @@ -3601,7 +3723,8 @@ static void pmac_ide_save(QEMUFile *f, void *opaque)
3601 3723  
3602 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 3728 uint8_t drive1_selected;
3606 3729 unsigned int i;
3607 3730  
... ... @@ -3622,7 +3745,8 @@ static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id)
3622 3745  
3623 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 3751 ide_reset(&s[0]);
3628 3752 ide_reset(&s[1]);
... ... @@ -3631,21 +3755,29 @@ static void pmac_ide_reset(void *opaque)
3631 3755 /* hd_table must contain 4 block drivers */
3632 3756 /* PowerMac uses memory mapped registers, not I/O. Return the memory
3633 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 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 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 3778 return pmac_ide_memory;
3648 3779 }
  3780 +#endif /* TARGET_PPC */
3649 3781  
3650 3782 /***********************************************************/
3651 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 284 }
285 285 dbdma = DBDMA_init(&dbdma_mem_index);
286 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 289 #else
290 290 pci_cmd646_ide_init(pci_bus, &hd[0], 0);
291 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 48 int nb_ide, int *ide_mem_index, int escc_mem_index);
49 49  
50 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 54 /* Heathrow PIC */
54 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 349 dbdma = DBDMA_init(&dbdma_mem_index);
350 350  
351 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 354 /* cuda also initialize ADB */
355 355 cuda_init(&cuda_mem_index, pic[0x12]);
... ...