]> Git Repo - qemu.git/blobdiff - hw/ppc_prep.c
pseries: Under kvm use guest cpu = host cpu by default
[qemu.git] / hw / ppc_prep.c
index 1cad17f6f8d8558e1d68b4ad0a0b1a2bd1378158..f22d5b98c5da1f3c3b9f6a1fd5a3140cbf88c180 100644 (file)
 #include "sysemu.h"
 #include "isa.h"
 #include "pci.h"
+#include "prep_pci.h"
+#include "usb-ohci.h"
 #include "ppc.h"
 #include "boards.h"
 #include "qemu-log.h"
 #include "ide.h"
+#include "loader.h"
+#include "mc146818rtc.h"
+#include "blockdev.h"
+#include "exec-memory.h"
 
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
@@ -77,7 +83,7 @@ static const int ide_irq[2] = { 13, 13 };
 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
 
-//static PITState *pit;
+//static ISADevice *pit;
 
 /* ISA IO ports bridge */
 #define PPC_IO_BASE 0x80000000
@@ -100,7 +106,7 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
 {
 #if 0
     int out;
-    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
+    out = pit_get_out(pit, 2, qemu_get_clock_ns(vm_clock));
     dummy_refresh_clock ^= 1;
     return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
         (dummy_refresh_clock << 4);
@@ -110,21 +116,22 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
 
 /* PCI intack register */
 /* Read-only register (?) */
-static void _PPC_intack_write (void *opaque,
-                               target_phys_addr_t addr, uint32_t value)
+static void PPC_intack_write (void *opaque, target_phys_addr_t addr,
+                              uint64_t value, unsigned size)
 {
 #if 0
-    printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", __func__, addr,
+    printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx64 "\n", __func__, addr,
            value);
 #endif
 }
 
-static inline uint32_t _PPC_intack_read(target_phys_addr_t addr)
+static uint64_t PPC_intack_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
 {
     uint32_t retval = 0;
 
     if ((addr & 0xf) == 0)
-        retval = pic_intack_read(isa_pic);
+        retval = pic_read_irq(isa_pic);
 #if 0
     printf("%s: 0x" TARGET_FMT_plx " <= %08" PRIx32 "\n", __func__, addr,
            retval);
@@ -133,39 +140,10 @@ static inline uint32_t _PPC_intack_read(target_phys_addr_t addr)
     return retval;
 }
 
-static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
-{
-    return _PPC_intack_read(addr);
-}
-
-static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-    return bswap16(_PPC_intack_read(addr));
-#else
-    return _PPC_intack_read(addr);
-#endif
-}
-
-static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-    return bswap32(_PPC_intack_read(addr));
-#else
-    return _PPC_intack_read(addr);
-#endif
-}
-
-static CPUWriteMemoryFunc * const PPC_intack_write[] = {
-    &_PPC_intack_write,
-    &_PPC_intack_write,
-    &_PPC_intack_write,
-};
-
-static CPUReadMemoryFunc * const PPC_intack_read[] = {
-    &PPC_intack_readb,
-    &PPC_intack_readw,
-    &PPC_intack_readl,
+static const MemoryRegionOps PPC_intack_ops = {
+    .read = PPC_intack_read,
+    .write = PPC_intack_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /* PowerPC control and status registers */
@@ -205,9 +183,6 @@ static void PPC_XCSR_writeb (void *opaque,
 static void PPC_XCSR_writew (void *opaque,
                              target_phys_addr_t addr, uint32_t value)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap16(value);
-#endif
     printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", __func__, addr,
            value);
 }
@@ -215,9 +190,6 @@ static void PPC_XCSR_writew (void *opaque,
 static void PPC_XCSR_writel (void *opaque,
                              target_phys_addr_t addr, uint32_t value)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap32(value);
-#endif
     printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", __func__, addr,
            value);
 }
@@ -238,9 +210,6 @@ static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
 
     printf("%s: 0x" TARGET_FMT_plx " <= %08" PRIx32 "\n", __func__, addr,
            retval);
-#ifdef TARGET_WORDS_BIGENDIAN
-    retval = bswap16(retval);
-#endif
 
     return retval;
 }
@@ -251,30 +220,24 @@ static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
 
     printf("%s: 0x" TARGET_FMT_plx " <= %08" PRIx32 "\n", __func__, addr,
            retval);
-#ifdef TARGET_WORDS_BIGENDIAN
-    retval = bswap32(retval);
-#endif
 
     return retval;
 }
 
-static CPUWriteMemoryFunc * const PPC_XCSR_write[] = {
-    &PPC_XCSR_writeb,
-    &PPC_XCSR_writew,
-    &PPC_XCSR_writel,
+static const MemoryRegionOps PPC_XCSR_ops = {
+    .old_mmio = {
+        .read = { PPC_XCSR_readb, PPC_XCSR_readw, PPC_XCSR_readl, },
+        .write = { PPC_XCSR_writeb, PPC_XCSR_writew, PPC_XCSR_writel, },
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const PPC_XCSR_read[] = {
-    &PPC_XCSR_readb,
-    &PPC_XCSR_readw,
-    &PPC_XCSR_readl,
-};
 #endif
 
 /* Fake super-io ports for PREP platform (Intel 82378ZB) */
 typedef struct sysctrl_t {
     qemu_irq reset_irq;
-    m48t59_t *nvram;
+    M48t59State *nvram;
     uint8_t state;
     uint8_t syscontrol;
     uint8_t fake_io[2];
@@ -459,7 +422,7 @@ static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
     sysctrl_t *sysctrl = opaque;
 
     addr = prep_IO_address(sysctrl, addr);
-    cpu_outb(NULL, addr, value);
+    cpu_outb(addr, value);
 }
 
 static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
@@ -468,7 +431,7 @@ static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
     uint32_t ret;
 
     addr = prep_IO_address(sysctrl, addr);
-    ret = cpu_inb(NULL, addr);
+    ret = cpu_inb(addr);
 
     return ret;
 }
@@ -479,11 +442,8 @@ static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
     sysctrl_t *sysctrl = opaque;
 
     addr = prep_IO_address(sysctrl, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap16(value);
-#endif
     PPC_IO_DPRINTF("0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", addr, value);
-    cpu_outw(NULL, addr, value);
+    cpu_outw(addr, value);
 }
 
 static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
@@ -492,10 +452,7 @@ static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
     uint32_t ret;
 
     addr = prep_IO_address(sysctrl, addr);
-    ret = cpu_inw(NULL, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
-    ret = bswap16(ret);
-#endif
+    ret = cpu_inw(addr);
     PPC_IO_DPRINTF("0x" TARGET_FMT_plx " <= 0x%08" PRIx32 "\n", addr, ret);
 
     return ret;
@@ -507,11 +464,8 @@ static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
     sysctrl_t *sysctrl = opaque;
 
     addr = prep_IO_address(sysctrl, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap32(value);
-#endif
     PPC_IO_DPRINTF("0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", addr, value);
-    cpu_outl(NULL, addr, value);
+    cpu_outl(addr, value);
 }
 
 static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
@@ -520,29 +474,31 @@ static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
     uint32_t ret;
 
     addr = prep_IO_address(sysctrl, addr);
-    ret = cpu_inl(NULL, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
-    ret = bswap32(ret);
-#endif
+    ret = cpu_inl(addr);
     PPC_IO_DPRINTF("0x" TARGET_FMT_plx " <= 0x%08" PRIx32 "\n", addr, ret);
 
     return ret;
 }
 
-static CPUWriteMemoryFunc * const PPC_prep_io_write[] = {
-    &PPC_prep_io_writeb,
-    &PPC_prep_io_writew,
-    &PPC_prep_io_writel,
-};
-
-static CPUReadMemoryFunc * const PPC_prep_io_read[] = {
-    &PPC_prep_io_readb,
-    &PPC_prep_io_readw,
-    &PPC_prep_io_readl,
+static const MemoryRegionOps PPC_prep_io_ops = {
+    .old_mmio = {
+        .read = { PPC_prep_io_readb, PPC_prep_io_readw, PPC_prep_io_readl },
+        .write = { PPC_prep_io_writeb, PPC_prep_io_writew, PPC_prep_io_writel },
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 #define NVRAM_SIZE        0x2000
 
+static void cpu_request_exit(void *opaque, int irq, int level)
+{
+    CPUState *env = cpu_single_env;
+
+    if (env && level) {
+        cpu_exit(env);
+    }
+}
+
 /* PowerPC PREP hardware initialisation */
 static void ppc_prep_init (ram_addr_t ram_size,
                            const char *boot_device,
@@ -551,28 +507,35 @@ static void ppc_prep_init (ram_addr_t ram_size,
                            const char *initrd_filename,
                            const char *cpu_model)
 {
-    CPUState *env = NULL, *envs[MAX_CPUS];
+    MemoryRegion *sysmem = get_system_memory();
+    CPUState *env = NULL;
     char *filename;
     nvram_t nvram;
-    m48t59_t *m48t59;
-    int PPC_io_memory;
+    M48t59State *m48t59;
+    MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);
+    MemoryRegion *intack = g_new(MemoryRegion, 1);
+#if 0
+    MemoryRegion *xcsr = g_new(MemoryRegion, 1);
+#endif
     int linux_boot, i, nb_nics1, bios_size;
-    ram_addr_t ram_offset, bios_offset;
-    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    uint32_t kernel_base, initrd_base;
+    long kernel_size, initrd_size;
     PCIBus *pci_bus;
     qemu_irq *i8259;
+    qemu_irq *cpu_exit_irq;
     int ppc_boot_device;
-    DriveInfo *dinfo;
-    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BlockDriverState *fd[MAX_FD];
+    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    DriveInfo *fd[MAX_FD];
 
-    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
+    sysctrl = g_malloc0(sizeof(sysctrl_t));
 
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
     if (cpu_model == NULL)
-        cpu_model = "default";
+        cpu_model = "602";
     for (i = 0; i < smp_cpus; i++) {
         env = cpu_init(cpu_model);
         if (!env) {
@@ -586,16 +549,15 @@ static void ppc_prep_init (ram_addr_t ram_size,
             /* Set time-base frequency to 100 Mhz */
             cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
         }
-        qemu_register_reset(&cpu_ppc_reset, env);
-        envs[i] = env;
+        qemu_register_reset((QEMUResetHandler*)&cpu_reset, env);
     }
 
     /* allocate RAM */
-    ram_offset = qemu_ram_alloc(ram_size);
-    cpu_register_physical_memory(0, ram_size, ram_offset);
+    memory_region_init_ram(ram, NULL, "ppc_prep.ram", ram_size);
+    memory_region_add_subregion(sysmem, 0, ram);
 
     /* allocate and load BIOS */
-    bios_offset = qemu_ram_alloc(BIOS_SIZE);
+    memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE);
     if (bios_name == NULL)
         bios_name = BIOS_FILENAME;
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
@@ -608,18 +570,15 @@ static void ppc_prep_init (ram_addr_t ram_size,
         target_phys_addr_t bios_addr;
         bios_size = (bios_size + 0xfff) & ~0xfff;
         bios_addr = (uint32_t)(-bios_size);
-        cpu_register_physical_memory(bios_addr, bios_size,
-                                     bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(sysmem, bios_addr, bios);
         bios_size = load_image_targphys(filename, bios_addr, bios_size);
     }
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
         hw_error("qemu: could not load PPC PREP bios '%s'\n", bios_name);
     }
     if (filename) {
-        qemu_free(filename);
-    }
-    if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {
-        hw_error("PowerPC 601 / 620 / 970 need a 1MB BIOS\n");
+        g_free(filename);
     }
 
     if (linux_boot) {
@@ -668,59 +627,56 @@ static void ppc_prep_init (ram_addr_t ram_size,
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
+    /* Hmm, prep has no pci-isa bridge ??? */
+    isa_bus_new(NULL, get_system_io());
     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
-    pci_bus = pci_prep_init(i8259);
+    pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io());
+    isa_bus_irqs(i8259);
     //    pci_bus = i440fx_init();
     /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
-    PPC_io_memory = cpu_register_io_memory(PPC_prep_io_read,
-                                           PPC_prep_io_write, sysctrl);
-    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
+    memory_region_init_io(PPC_io_memory, &PPC_prep_io_ops, sysctrl,
+                          "ppc-io", 0x00800000);
+    memory_region_add_subregion(sysmem, 0x80000000, PPC_io_memory);
 
     /* init basic PC hardware */
-    pci_vga_init(pci_bus, 0, 0);
+    pci_vga_init(pci_bus);
     //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
-    //    pit = pit_init(0x40, i8259[0]);
-    rtc_init(0x70, i8259[8], 2000);
+    //    pit = pit_init(0x40, 0);
+    rtc_init(2000, NULL);
 
-    serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
+    if (serial_hds[0])
+        serial_isa_init(0, serial_hds[0]);
     nb_nics1 = nb_nics;
     if (nb_nics1 > NE2000_NB_MAX)
         nb_nics1 = NE2000_NB_MAX;
     for(i = 0; i < nb_nics1; i++) {
         if (nd_table[i].model == NULL) {
-           nd_table[i].model = "ne2k_isa";
+           nd_table[i].model = g_strdup("ne2k_isa");
         }
         if (strcmp(nd_table[i].model, "ne2k_isa") == 0) {
-            isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
+            isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
         } else {
-            pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
+            pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
         }
     }
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-        hd[i] = dinfo ? dinfo->bdrv : NULL;
-    }
-
+    ide_drive_get(hd, MAX_IDE_BUS);
     for(i = 0; i < MAX_IDE_BUS; i++) {
-        isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
+        isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
                      hd[2 * i],
                     hd[2 * i + 1]);
     }
-    i8042_init(i8259[1], i8259[12], 0x60);
-    DMA_init(1);
+    isa_create_simple("i8042");
+
+    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+    DMA_init(1, cpu_exit_irq);
+
     //    SB16_init();
 
     for(i = 0; i < MAX_FD; i++) {
-        dinfo = drive_get(IF_FLOPPY, 0, i);
-        fd[i] = dinfo ? dinfo->bdrv : NULL;
+        fd[i] = drive_get(IF_FLOPPY, 0, i);
     }
-    fdctrl_init_isa(6, 2, 0x3f0, fd);
+    fdctrl_init_isa(fd);
 
     /* Register speaker port */
     register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
@@ -735,18 +691,16 @@ static void ppc_prep_init (ram_addr_t ram_size,
     register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
     register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
     /* PCI intack location */
-    PPC_io_memory = cpu_register_io_memory(PPC_intack_read,
-                                           PPC_intack_write, NULL);
-    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
+    memory_region_init_io(intack, &PPC_intack_ops, NULL, "ppc-intack", 4);
+    memory_region_add_subregion(sysmem, 0xBFFFFFF0, intack);
     /* PowerPC control and status register group */
 #if 0
-    PPC_io_memory = cpu_register_io_memory(PPC_XCSR_read, PPC_XCSR_write,
-                                           NULL);
-    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
+    memory_region_init_io(xcsr, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000);
+    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);
 #endif
 
     if (usb_enabled) {
-        usb_ohci_init_pci(pci_bus, 3, -1);
+        usb_ohci_init_pci(pci_bus, -1);
     }
 
     m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
This page took 0.03701 seconds and 4 git commands to generate.