]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/ppc_prep.c
Introduce TCP live migration protocol
[mirror_qemu.git] / hw / ppc_prep.c
index 5474d512ceb548f78abaa5f266cb502e5542b72b..944935d2988e855c3af17d900a31946f12cd09e2 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "vl.h"
+#include "hw.h"
+#include "nvram.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "sysemu.h"
+#include "isa.h"
+#include "pci.h"
+#include "ppc.h"
+#include "boards.h"
+#include "qemu-log.h"
 
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
 
+#define MAX_IDE_BUS 2
+
 #define BIOS_FILENAME "ppc_rom.bin"
 #define KERNEL_LOAD_ADDR 0x01000000
 #define INITRD_LOAD_ADDR 0x01800000
 
-extern int loglevel;
-extern FILE *logfile;
-
 #if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
 #define DEBUG_PPC_IO
 #endif
@@ -104,7 +113,7 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
 static void _PPC_intack_write (void *opaque,
                                target_phys_addr_t addr, uint32_t value)
 {
-    //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
+//    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
 }
 
 static always_inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
@@ -113,7 +122,7 @@ static always_inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
 
     if (addr == 0xBFFFFFF0)
         retval = pic_intack_read(isa_pic);
-    //   printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
+//   printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
 
     return retval;
 }
@@ -183,7 +192,7 @@ static struct {
 static void PPC_XCSR_writeb (void *opaque,
                              target_phys_addr_t addr, uint32_t value)
 {
-    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
 }
 
 static void PPC_XCSR_writew (void *opaque,
@@ -192,7 +201,7 @@ static void PPC_XCSR_writew (void *opaque,
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap16(value);
 #endif
-    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
 }
 
 static void PPC_XCSR_writel (void *opaque,
@@ -201,14 +210,14 @@ static void PPC_XCSR_writel (void *opaque,
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
 #endif
-    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
 }
 
 static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
-    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
 
     return retval;
 }
@@ -217,7 +226,7 @@ static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
-    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
 #ifdef TARGET_WORDS_BIGENDIAN
     retval = bswap16(retval);
 #endif
@@ -229,7 +238,7 @@ static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
-    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
 #ifdef TARGET_WORDS_BIGENDIAN
     retval = bswap32(retval);
 #endif
@@ -271,7 +280,8 @@ static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
 {
     sysctrl_t *sysctrl = opaque;
 
-    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
+    PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
+                   val);
     sysctrl->fake_io[addr - 0x0398] = val;
 }
 
@@ -279,7 +289,7 @@ static uint32_t PREP_io_read (void *opaque, uint32_t addr)
 {
     sysctrl_t *sysctrl = opaque;
 
-    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
+    PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
                    sysctrl->fake_io[addr - 0x0398]);
     return sysctrl->fake_io[addr - 0x0398];
 }
@@ -288,7 +298,8 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
 {
     sysctrl_t *sysctrl = opaque;
 
-    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
+    PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n",
+                   addr - PPC_IO_BASE, val);
     switch (addr) {
     case 0x0092:
         /* Special port 92 */
@@ -344,8 +355,8 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
         sysctrl->contiguous_map = val & 0x01;
         break;
     default:
-        printf("ERROR: unaffected IO port write: %04lx => %02x\n",
-               (long)addr, val);
+        printf("ERROR: unaffected IO port write: %04" PRIx32
+               " => %02" PRIx32"\n", addr, val);
         break;
     }
 }
@@ -407,10 +418,11 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
         retval = sysctrl->contiguous_map;
         break;
     default:
-        printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
+        printf("ERROR: unaffected IO port: %04" PRIx32 " read\n", addr);
         break;
     }
-    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
+    PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n",
+                   addr - PPC_IO_BASE, retval);
 
     return retval;
 }
@@ -459,7 +471,7 @@ static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap16(value);
 #endif
-    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
+    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
     cpu_outw(NULL, addr, value);
 }
 
@@ -473,7 +485,7 @@ static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
 #ifdef TARGET_WORDS_BIGENDIAN
     ret = bswap16(ret);
 #endif
-    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
+    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
 
     return ret;
 }
@@ -487,7 +499,7 @@ static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
 #endif
-    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
+    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
     cpu_outl(NULL, addr, value);
 }
 
@@ -501,7 +513,7 @@ static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
 #ifdef TARGET_WORDS_BIGENDIAN
     ret = bswap32(ret);
 #endif
-    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
+    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
 
     return ret;
 }
@@ -521,14 +533,14 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = {
 #define NVRAM_SIZE        0x2000
 
 /* PowerPC PREP hardware initialisation */
-static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_device,
-                           DisplayState *ds, const char **fd_filename,
-                           int snapshot, const char *kernel_filename,
+static void ppc_prep_init (ram_addr_t ram_size, int vga_ram_size,
+                           const char *boot_device, DisplayState *ds,
+                           const char *kernel_filename,
                            const char *kernel_cmdline,
                            const char *initrd_filename,
                            const char *cpu_model)
 {
-    CPUState *env, *envs[MAX_CPUS];
+    CPUState *env = NULL, *envs[MAX_CPUS];
     char buf[1024];
     nvram_t nvram;
     m48t59_t *m48t59;
@@ -538,7 +550,10 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
     uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
     PCIBus *pci_bus;
     qemu_irq *i8259;
-    int ppc_boot_device = boot_device[0];
+    int ppc_boot_device;
+    int index;
+    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    BlockDriverState *fd[MAX_FD];
 
     sysctrl = qemu_mallocz(sizeof(sysctrl_t));
     if (sysctrl == NULL)
@@ -555,10 +570,14 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
-        /* Set time-base frequency to 100 Mhz */
-        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+        if (env->flags & POWERPC_FLAG_RTC_CLK) {
+            /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
+            cpu_ppc_tb_init(env, 7812500UL);
+        } else {
+            /* Set time-base frequency to 100 Mhz */
+            cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+        }
         qemu_register_reset(&cpu_ppc_reset, env);
-        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
         envs[i] = env;
     }
 
@@ -611,6 +630,18 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
         kernel_size = 0;
         initrd_base = 0;
         initrd_size = 0;
+        ppc_boot_device = '\0';
+        /* For now, OHW cannot boot from the network. */
+        for (i = 0; boot_device[i] != '\0'; i++) {
+            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
+                ppc_boot_device = boot_device[i];
+                break;
+            }
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for Mac99 machine\n");
+            exit(1);
+        }
     }
 
     isa_mem_base = 0xc0000000;
@@ -633,7 +664,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
     //    pit = pit_init(0x40, i8259[0]);
     rtc_init(0x70, i8259[8]);
 
-    serial_init(0x3f8, i8259[4], serial_hds[0]);
+    serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
     nb_nics1 = nb_nics;
     if (nb_nics1 > NE2000_NB_MAX)
         nb_nics1 = NE2000_NB_MAX;
@@ -646,16 +677,37 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
         }
     }
 
-    for(i = 0; i < 2; i++) {
+    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++) {
+        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        if (index != -1)
+            hd[i] = drives_table[index].bdrv;
+        else
+            hd[i] = NULL;
+    }
+
+    for(i = 0; i < MAX_IDE_BUS; i++) {
         isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
-                     bs_table[2 * i], bs_table[2 * i + 1]);
+                     hd[2 * i],
+                    hd[2 * i + 1]);
     }
     i8042_init(i8259[1], i8259[12], 0x60);
     DMA_init(1);
     //    AUD_init();
     //    SB16_init();
 
-    fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table);
+    for(i = 0; i < MAX_FD; i++) {
+        index = drive_get_index(IF_FLOPPY, 0, i);
+        if (index != -1)
+            fd[i] = drives_table[index].bdrv;
+        else
+            fd[i] = NULL;
+    }
+    fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
 
     /* Register speaker port */
     register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
@@ -706,7 +758,9 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
 }
 
 QEMUMachine prep_machine = {
-    "prep",
-    "PowerPC PREP platform",
-    ppc_prep_init,
+    .name = "prep",
+    .desc = "PowerPC PREP platform",
+    .init = ppc_prep_init,
+    .ram_require = BIOS_SIZE + VGA_RAM_SIZE,
+    .max_cpus = 1,
 };