diff options
-rw-r--r-- | hw/pci.c | 10 | ||||
-rw-r--r-- | hw/ppc_prep.c | 125 |
2 files changed, 125 insertions, 10 deletions
@@ -694,6 +694,16 @@ PCIBus *pci_prep_init(void) s = pci_register_bus(); s->set_irq = prep_set_irq; + register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s); + register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s); + + register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s); + register_ioport_write(0xcfc, 4, 2, pci_data_writew, s); + register_ioport_write(0xcfc, 4, 4, pci_data_writel, s); + register_ioport_read(0xcfc, 4, 1, pci_data_readb, s); + register_ioport_read(0xcfc, 4, 2, pci_data_readw, s); + register_ioport_read(0xcfc, 4, 4, pci_data_readl, s); + PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, PPC_PCIIO_write, s); cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index c93b72faeb..06951e542d 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -249,6 +249,7 @@ typedef struct sysctrl_t { uint8_t state; uint8_t syscontrol; uint8_t fake_io[2]; + int contiguous_map; } sysctrl_t; enum { @@ -328,10 +329,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) break; case 0x0850: /* I/O map type register */ - if (!(val & 0x01)) { - printf("No support for non-continuous I/O map mode\n"); - abort(); - } + sysctrl->contiguous_map = val & 0x01; break; default: printf("ERROR: unaffected IO port write: %04lx => %02x\n", @@ -375,6 +373,9 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) /* Motorola base module extended feature register */ retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */ break; + case 0x0814: + /* L2 invalidate: don't care */ + break; case 0x0818: /* Keylock */ retval = 0x00; @@ -391,7 +392,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) break; case 0x0850: /* I/O map type register */ - retval = 0x01; + retval = sysctrl->contiguous_map; break; default: printf("ERROR: unaffected IO port: %04lx read\n", (long)addr); @@ -402,6 +403,108 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) return retval; } +static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl, + target_phys_addr_t addr) +{ + if (sysctrl->contiguous_map == 0) { + /* 64 KB contiguous space for IOs */ + addr &= 0xFFFF; + } else { + /* 8 MB non-contiguous space for IOs */ + addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7); + } + + return addr; +} + +static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + sysctrl_t *sysctrl = opaque; + + addr = prep_IO_address(sysctrl, addr); + cpu_outb(NULL, addr, value); +} + +static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr) +{ + sysctrl_t *sysctrl = opaque; + uint32_t ret; + + addr = prep_IO_address(sysctrl, addr); + ret = cpu_inb(NULL, addr); + + return ret; +} + +static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + sysctrl_t *sysctrl = opaque; + + addr = prep_IO_address(sysctrl, addr); +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap16(value); +#endif + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value); + cpu_outw(NULL, addr, value); +} + +static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr) +{ + sysctrl_t *sysctrl = opaque; + uint32_t ret; + + addr = prep_IO_address(sysctrl, addr); + ret = cpu_inw(NULL, addr); +#ifdef TARGET_WORDS_BIGENDIAN + ret = bswap16(ret); +#endif + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret); + + return ret; +} + +static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + sysctrl_t *sysctrl = opaque; + + addr = prep_IO_address(sysctrl, addr); +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap32(value); +#endif + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value); + cpu_outl(NULL, addr, value); +} + +static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr) +{ + sysctrl_t *sysctrl = opaque; + uint32_t ret; + + addr = prep_IO_address(sysctrl, addr); + ret = cpu_inl(NULL, addr); +#ifdef TARGET_WORDS_BIGENDIAN + ret = bswap32(ret); +#endif + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret); + + return ret; +} + +CPUWriteMemoryFunc *PPC_prep_io_write[] = { + &PPC_prep_io_writeb, + &PPC_prep_io_writew, + &PPC_prep_io_writel, +}; + +CPUReadMemoryFunc *PPC_prep_io_read[] = { + &PPC_prep_io_readb, + &PPC_prep_io_readw, + &PPC_prep_io_readl, +}; + extern CPUPPCState *global_env; #define NVRAM_SIZE 0x2000 @@ -472,16 +575,18 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, initrd_size = 0; } - /* Register CPU as a 74x/75x */ - cpu_ppc_register(cpu_single_env, 0x00080000); + /* Register CPU as a 604 */ + cpu_ppc_register(cpu_single_env, 0x00040000); /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); isa_mem_base = 0xc0000000; pci_bus = pci_prep_init(); - /* Register 64 KB of ISA IO space */ - PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); - cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory); + // pci_bus = i440fx_init(); + /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ + PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read, + PPC_prep_io_write, sysctrl); + cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory); /* init basic PC hardware */ vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, |