Commit 3cbee15b9a6be17645e908bf7706d582c3e17156

Authored by j_mayer
1 parent 897b4c6c

* sort the PowerPC target object files

* make PowerPC NVRAM accessors generic to be able to use a MacIO NVRAM
  instead of the M48T59 one
* split PowerMac targets code:
 - move all PowerMac related definitions and prototypes into hw/ppc_mac.h
 - add hw/mac_dbdma.c, hw/mac_nvram.c and macio.c
   which implements shared PowerMac devices
 - define the g3bw machine in a new hw/ppc_oldworld.c file
* Fix the g3bw target:
 - fix the Grackle host PCI device
 - connect the Heathrow PIC to the PowerPC 6xx bus pins


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3475 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -469,13 +469,20 @@ VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmport.o vmware_vga.o @@ -469,13 +469,20 @@ VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmport.o vmware_vga.o
469 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE 469 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
470 endif 470 endif
471 ifeq ($(TARGET_BASE_ARCH), ppc) 471 ifeq ($(TARGET_BASE_ARCH), ppc)
472 -VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)  
473 -VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o pflash_cfi02.o  
474 -VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o  
475 -VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o  
476 -# PowerPC 4xx boards  
477 -VL_OBJS+= ppc4xx_devs.o ppc405_uc.o ppc405_boards.o  
478 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE 472 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
  473 +# shared objects
  474 +VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o $(AUDIODRV)
  475 +# PREP target
  476 +VL_OBJS+= pckbd.o ps2.o serial.o i8259.o i8254.o fdc.o m48t59.o mc146818rtc.o
  477 +VL_OBJS+= prep_pci.o ppc_prep.o
  478 +# Mac shared devices
  479 +VL_OBJS+= macio.o cuda.o adb.o mac_nvram.o mac_dbdma.o
  480 +# OldWorld PowerMac
  481 +VL_OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
  482 +# NewWorld PowerMac
  483 +VL_OBJS+= unin_pci.o ppc_chrp.o
  484 +# PowerPC 4xx boards
  485 +VL_OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
479 endif 486 endif
480 ifeq ($(TARGET_BASE_ARCH), mips) 487 ifeq ($(TARGET_BASE_ARCH), mips)
481 VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o 488 VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
hw/cuda.c
1 /* 1 /*
2 - * QEMU CUDA support 2 + * QEMU PowerMac CUDA device support
3 * 3 *
4 - * Copyright (c) 2004 Fabrice Bellard 4 + * Copyright (c) 2004-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
5 * 6 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 8 * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +23,7 @@ @@ -22,6 +23,7 @@
22 * THE SOFTWARE. 23 * THE SOFTWARE.
23 */ 24 */
24 #include "vl.h" 25 #include "vl.h"
  26 +#include "ppc_mac.h"
25 27
26 /* XXX: implement all timer modes */ 28 /* XXX: implement all timer modes */
27 29
@@ -634,10 +636,9 @@ static CPUReadMemoryFunc *cuda_read[] = { @@ -634,10 +636,9 @@ static CPUReadMemoryFunc *cuda_read[] = {
634 &cuda_readl, 636 &cuda_readl,
635 }; 637 };
636 638
637 -int cuda_init(qemu_irq irq) 639 +void cuda_init (int *cuda_mem_index, qemu_irq irq)
638 { 640 {
639 CUDAState *s = &cuda_state; 641 CUDAState *s = &cuda_state;
640 - int cuda_mem_index;  
641 642
642 s->irq = irq; 643 s->irq = irq;
643 644
@@ -653,6 +654,5 @@ int cuda_init(qemu_irq irq) @@ -653,6 +654,5 @@ int cuda_init(qemu_irq irq)
653 set_counter(s, &s->timers[1], 0xffff); 654 set_counter(s, &s->timers[1], 0xffff);
654 655
655 s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); 656 s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
656 - cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);  
657 - return cuda_mem_index; 657 + *cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
658 } 658 }
hw/grackle_pci.c
1 /* 1 /*
2 - * QEMU Grackle (heathrow PPC) PCI host 2 + * QEMU Grackle PCI host (heathrow OldWorld PowerMac)
3 * 3 *
4 - * Copyright (c) 2006 Fabrice Bellard 4 + * Copyright (c) 2006-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
5 * 6 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 8 * of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +24,7 @@ @@ -23,6 +24,7 @@
23 */ 24 */
24 25
25 #include "vl.h" 26 #include "vl.h"
  27 +#include "ppc_mac.h"
26 typedef target_phys_addr_t pci_addr_t; 28 typedef target_phys_addr_t pci_addr_t;
27 #include "pci_host.h" 29 #include "pci_host.h"
28 30
@@ -82,7 +84,7 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num) @@ -82,7 +84,7 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
82 84
83 static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level) 85 static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level)
84 { 86 {
85 - qemu_set_irq(pic[irq_num + 8], level); 87 + qemu_set_irq(pic[irq_num + 0x15], level);
86 } 88 }
87 89
88 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) 90 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
@@ -93,7 +95,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) @@ -93,7 +95,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
93 95
94 s = qemu_mallocz(sizeof(GrackleState)); 96 s = qemu_mallocz(sizeof(GrackleState));
95 s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq, 97 s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
96 - pic, 0, 0); 98 + pic, 0, 4);
97 99
98 pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, 100 pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
99 pci_grackle_config_write, s); 101 pci_grackle_config_write, s);
hw/heathrow_pic.c
1 /* 1 /*
2 - * Heathrow PIC support (standard PowerMac PIC) 2 + * Heathrow PIC support (OldWorld PowerMac)
3 * 3 *
4 - * Copyright (c) 2005 Fabrice Bellard 4 + * Copyright (c) 2005-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
5 * 6 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 8 * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +23,7 @@ @@ -22,6 +23,7 @@
22 * THE SOFTWARE. 23 * THE SOFTWARE.
23 */ 24 */
24 #include "vl.h" 25 #include "vl.h"
  26 +#include "ppc_mac.h"
25 27
26 //#define DEBUG 28 //#define DEBUG
27 29
@@ -34,6 +36,7 @@ typedef struct HeathrowPIC { @@ -34,6 +36,7 @@ typedef struct HeathrowPIC {
34 36
35 typedef struct HeathrowPICS { 37 typedef struct HeathrowPICS {
36 HeathrowPIC pics[2]; 38 HeathrowPIC pics[2];
  39 + qemu_irq *irqs;
37 } HeathrowPICS; 40 } HeathrowPICS;
38 41
39 static inline int check_irq(HeathrowPIC *pic) 42 static inline int check_irq(HeathrowPIC *pic)
@@ -45,9 +48,9 @@ static inline int check_irq(HeathrowPIC *pic) @@ -45,9 +48,9 @@ static inline int check_irq(HeathrowPIC *pic)
45 static void heathrow_pic_update(HeathrowPICS *s) 48 static void heathrow_pic_update(HeathrowPICS *s)
46 { 49 {
47 if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) { 50 if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
48 - cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD); 51 + qemu_irq_raise(s->irqs[0]);
49 } else { 52 } else {
50 - cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD); 53 + qemu_irq_lower(s->irqs[0]);
51 } 54 }
52 } 55 }
53 56
@@ -57,12 +60,13 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -57,12 +60,13 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
57 HeathrowPIC *pic; 60 HeathrowPIC *pic;
58 unsigned int n; 61 unsigned int n;
59 62
  63 +#ifdef TARGET_WORDS_BIGENDIAN
60 value = bswap32(value); 64 value = bswap32(value);
61 -#ifdef DEBUG  
62 - printf("pic_writel: %08x: %08x\n",  
63 - addr, value);  
64 #endif 65 #endif
65 n = ((addr & 0xfff) - 0x10) >> 4; 66 n = ((addr & 0xfff) - 0x10) >> 4;
  67 +#ifdef DEBUG
  68 + printf("pic_writel: " PADDRX " %u: %08x\n", addr, n, value);
  69 +#endif
66 if (n >= 2) 70 if (n >= 2)
67 return; 71 return;
68 pic = &s->pics[n]; 72 pic = &s->pics[n];
@@ -110,10 +114,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) @@ -110,10 +114,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
110 } 114 }
111 } 115 }
112 #ifdef DEBUG 116 #ifdef DEBUG
113 - printf("pic_readl: %08x: %08x\n",  
114 - addr, value); 117 + printf("pic_readl: " PADDRX " %u: %08x\n", addr, n, value);
115 #endif 118 #endif
  119 +#ifdef TARGET_WORDS_BIGENDIAN
116 value = bswap32(value); 120 value = bswap32(value);
  121 +#endif
117 return value; 122 return value;
118 } 123 }
119 124
@@ -156,13 +161,17 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level) @@ -156,13 +161,17 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level)
156 heathrow_pic_update(s); 161 heathrow_pic_update(s);
157 } 162 }
158 163
159 -qemu_irq *heathrow_pic_init(int *pmem_index) 164 +qemu_irq *heathrow_pic_init(int *pmem_index,
  165 + int nb_cpus, qemu_irq **irqs)
160 { 166 {
161 HeathrowPICS *s; 167 HeathrowPICS *s;
162 168
163 s = qemu_mallocz(sizeof(HeathrowPICS)); 169 s = qemu_mallocz(sizeof(HeathrowPICS));
164 s->pics[0].level_triggered = 0; 170 s->pics[0].level_triggered = 0;
165 s->pics[1].level_triggered = 0x1ff00000; 171 s->pics[1].level_triggered = 0x1ff00000;
  172 + /* only 1 CPU */
  173 + s->irqs = irqs[0];
166 *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s); 174 *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
  175 +
167 return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64); 176 return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
168 } 177 }
hw/mac_dbdma.c 0 โ†’ 100644
  1 +/*
  2 + * PowerMac descriptor-based DMA emulation
  3 + *
  4 + * Copyright (c) 2005-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +#include "vl.h"
  26 +#include "ppc_mac.h"
  27 +
  28 +/* DBDMA: currently no op - should suffice right now */
  29 +
  30 +static void dbdma_writeb (void *opaque,
  31 + target_phys_addr_t addr, uint32_t value)
  32 +{
  33 + printf("%s: 0x" PADDRX " <= 0x%08x\n", __func__, addr, value);
  34 +}
  35 +
  36 +static void dbdma_writew (void *opaque,
  37 + target_phys_addr_t addr, uint32_t value)
  38 +{
  39 +}
  40 +
  41 +static void dbdma_writel (void *opaque,
  42 + target_phys_addr_t addr, uint32_t value)
  43 +{
  44 +}
  45 +
  46 +static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
  47 +{
  48 + printf("%s: 0x" PADDRX " => 0x00000000\n", __func__, addr);
  49 +
  50 + return 0;
  51 +}
  52 +
  53 +static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
  54 +{
  55 + return 0;
  56 +}
  57 +
  58 +static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
  59 +{
  60 + return 0;
  61 +}
  62 +
  63 +static CPUWriteMemoryFunc *dbdma_write[] = {
  64 + &dbdma_writeb,
  65 + &dbdma_writew,
  66 + &dbdma_writel,
  67 +};
  68 +
  69 +static CPUReadMemoryFunc *dbdma_read[] = {
  70 + &dbdma_readb,
  71 + &dbdma_readw,
  72 + &dbdma_readl,
  73 +};
  74 +
  75 +void dbdma_init (int *dbdma_mem_index)
  76 +{
  77 + *dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
  78 +}
  79 +
hw/mac_nvram.c 0 โ†’ 100644
  1 +/*
  2 + * PowerMac NVRAM emulation
  3 + *
  4 + * Copyright (c) 2005-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +#include "vl.h"
  26 +#include "ppc_mac.h"
  27 +
  28 +struct MacIONVRAMState {
  29 + uint8_t data[0x2000];
  30 +};
  31 +
  32 +/* Direct access to NVRAM */
  33 +uint32_t macio_nvram_read (void *opaque, uint32_t addr)
  34 +{
  35 + MacIONVRAMState *s = opaque;
  36 + uint32_t ret;
  37 +
  38 + // printf("%s: %p addr %04x\n", __func__, s, addr);
  39 + if (addr < 0x2000)
  40 + ret = s->data[addr];
  41 + else
  42 + ret = -1;
  43 +
  44 + return ret;
  45 +}
  46 +
  47 +void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
  48 +{
  49 + MacIONVRAMState *s = opaque;
  50 +
  51 + // printf("%s: %p addr %04x val %02x\n", __func__, s, addr, val);
  52 + if (addr < 0x2000)
  53 + s->data[addr] = val;
  54 +}
  55 +
  56 +/* macio style NVRAM device */
  57 +static void macio_nvram_writeb (void *opaque,
  58 + target_phys_addr_t addr, uint32_t value)
  59 +{
  60 + MacIONVRAMState *s = opaque;
  61 + addr = (addr >> 4) & 0x1fff;
  62 + s->data[addr] = value;
  63 + // printf("macio_nvram_writeb %04x = %02x\n", addr, value);
  64 +}
  65 +
  66 +static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
  67 +{
  68 + MacIONVRAMState *s = opaque;
  69 + uint32_t value;
  70 +
  71 + addr = (addr >> 4) & 0x1fff;
  72 + value = s->data[addr];
  73 + // printf("macio_nvram_readb %04x = %02x\n", addr, value);
  74 +
  75 + return value;
  76 +}
  77 +
  78 +static CPUWriteMemoryFunc *nvram_write[] = {
  79 + &macio_nvram_writeb,
  80 + &macio_nvram_writeb,
  81 + &macio_nvram_writeb,
  82 +};
  83 +
  84 +static CPUReadMemoryFunc *nvram_read[] = {
  85 + &macio_nvram_readb,
  86 + &macio_nvram_readb,
  87 + &macio_nvram_readb,
  88 +};
  89 +
  90 +MacIONVRAMState *macio_nvram_init (int *mem_index)
  91 +{
  92 + MacIONVRAMState *s;
  93 + s = qemu_mallocz(sizeof(MacIONVRAMState));
  94 + if (!s)
  95 + return NULL;
  96 + *mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
  97 +
  98 + return s;
  99 +}
  100 +
  101 +static uint8_t nvram_chksum (const uint8_t *buf, int n)
  102 +{
  103 + int sum, i;
  104 + sum = 0;
  105 + for(i = 0; i < n; i++)
  106 + sum += buf[i];
  107 + return (sum & 0xff) + (sum >> 8);
  108 +}
  109 +
  110 +/* set a free Mac OS NVRAM partition */
  111 +void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
  112 +{
  113 + uint8_t *buf;
  114 + char partition_name[12] = "wwwwwwwwwwww";
  115 +
  116 + buf = nvr->data;
  117 + buf[0] = 0x7f; /* free partition magic */
  118 + buf[1] = 0; /* checksum */
  119 + buf[2] = len >> 8;
  120 + buf[3] = len;
  121 + memcpy(buf + 4, partition_name, 12);
  122 + buf[1] = nvram_chksum(buf, 16);
  123 +}
hw/macio.c 0 โ†’ 100644
  1 +/*
  2 + * PowerMac MacIO device emulation
  3 + *
  4 + * Copyright (c) 2005-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +#include "vl.h"
  26 +#include "ppc_mac.h"
  27 +
  28 +typedef struct macio_state_t macio_state_t;
  29 +struct macio_state_t {
  30 + int is_oldworld;
  31 + int pic_mem_index;
  32 + int dbdma_mem_index;
  33 + int cuda_mem_index;
  34 + int nvram_mem_index;
  35 + int nb_ide;
  36 + int ide_mem_index[4];
  37 +};
  38 +
  39 +static void macio_map (PCIDevice *pci_dev, int region_num,
  40 + uint32_t addr, uint32_t size, int type)
  41 +{
  42 + macio_state_t *macio_state;
  43 + int i;
  44 +
  45 + macio_state = (macio_state_t *)(pci_dev + 1);
  46 + if (macio_state->pic_mem_index >= 0) {
  47 + if (macio_state->is_oldworld) {
  48 + /* Heathrow PIC */
  49 + cpu_register_physical_memory(addr + 0x00000, 0x1000,
  50 + macio_state->pic_mem_index);
  51 + } else {
  52 + /* OpenPIC */
  53 + cpu_register_physical_memory(addr + 0x40000, 0x40000,
  54 + macio_state->pic_mem_index);
  55 + }
  56 + }
  57 + if (macio_state->dbdma_mem_index >= 0) {
  58 + cpu_register_physical_memory(addr + 0x08000, 0x1000,
  59 + macio_state->dbdma_mem_index);
  60 + }
  61 + if (macio_state->cuda_mem_index >= 0) {
  62 + cpu_register_physical_memory(addr + 0x16000, 0x2000,
  63 + macio_state->cuda_mem_index);
  64 + }
  65 + for (i = 0; i < macio_state->nb_ide; i++) {
  66 + if (macio_state->ide_mem_index[i] >= 0) {
  67 + cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
  68 + macio_state->ide_mem_index[i]);
  69 + }
  70 + }
  71 + if (macio_state->nvram_mem_index >= 0) {
  72 + cpu_register_physical_memory(addr + 0x60000, 0x20000,
  73 + macio_state->nvram_mem_index);
  74 + }
  75 +}
  76 +
  77 +void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
  78 + int dbdma_mem_index, int cuda_mem_index, int nvram_mem_index,
  79 + int nb_ide, int *ide_mem_index)
  80 +{
  81 + PCIDevice *d;
  82 + macio_state_t *macio_state;
  83 + int i;
  84 +
  85 + d = pci_register_device(bus, "macio",
  86 + sizeof(PCIDevice) + sizeof(macio_state_t),
  87 + -1, NULL, NULL);
  88 + macio_state = (macio_state_t *)(d + 1);
  89 + macio_state->is_oldworld = is_oldworld;
  90 + macio_state->pic_mem_index = pic_mem_index;
  91 + macio_state->dbdma_mem_index = dbdma_mem_index;
  92 + macio_state->cuda_mem_index = cuda_mem_index;
  93 + macio_state->nvram_mem_index = nvram_mem_index;
  94 + if (nb_ide > 4)
  95 + nb_ide = 4;
  96 + macio_state->nb_ide = nb_ide;
  97 + for (i = 0; i < nb_ide; i++)
  98 + macio_state->ide_mem_index[i] = ide_mem_index[i];
  99 + for (; i < 4; i++)
  100 + macio_state->ide_mem_index[i] = -1;
  101 + /* Note: this code is strongly inspirated from the corresponding code
  102 + in PearPC */
  103 + d->config[0x00] = 0x6b; // vendor_id
  104 + d->config[0x01] = 0x10;
  105 + d->config[0x02] = device_id;
  106 + d->config[0x03] = device_id >> 8;
  107 +
  108 + d->config[0x0a] = 0x00; // class_sub = pci2pci
  109 + d->config[0x0b] = 0xff; // class_base = bridge
  110 + d->config[0x0e] = 0x00; // header_type
  111 +
  112 + d->config[0x3d] = 0x01; // interrupt on pin 1
  113 +
  114 + pci_register_io_region(d, 0, 0x80000,
  115 + PCI_ADDRESS_SPACE_MEM, macio_map);
  116 +}
hw/ppc.c
@@ -22,7 +22,6 @@ @@ -22,7 +22,6 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 -#include "m48t59.h"  
26 25
27 //#define PPC_DEBUG_IRQ 26 //#define PPC_DEBUG_IRQ
28 //#define PPC_DEBUG_TB 27 //#define PPC_DEBUG_TB
@@ -1240,63 +1239,75 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val) @@ -1240,63 +1239,75 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1240 1239
1241 /*****************************************************************************/ 1240 /*****************************************************************************/
1242 /* NVRAM helpers */ 1241 /* NVRAM helpers */
1243 -void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value) 1242 +static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
1244 { 1243 {
1245 - m48t59_write(nvram, addr, value); 1244 + return (*nvram->read_fn)(nvram->opaque, addr);;
1246 } 1245 }
1247 1246
1248 -uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr) 1247 +static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
1249 { 1248 {
1250 - return m48t59_read(nvram, addr); 1249 + (*nvram->write_fn)(nvram->opaque, addr, val);
1251 } 1250 }
1252 1251
1253 -void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) 1252 +void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
1254 { 1253 {
1255 - m48t59_write(nvram, addr, value >> 8);  
1256 - m48t59_write(nvram, addr + 1, value & 0xFF); 1254 + nvram_write(nvram, addr, value);
1257 } 1255 }
1258 1256
1259 -uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr) 1257 +uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
  1258 +{
  1259 + return nvram_read(nvram, addr);
  1260 +}
  1261 +
  1262 +void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
  1263 +{
  1264 + nvram_write(nvram, addr, value >> 8);
  1265 + nvram_write(nvram, addr + 1, value & 0xFF);
  1266 +}
  1267 +
  1268 +uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
1260 { 1269 {
1261 uint16_t tmp; 1270 uint16_t tmp;
1262 1271
1263 - tmp = m48t59_read(nvram, addr) << 8;  
1264 - tmp |= m48t59_read(nvram, addr + 1); 1272 + tmp = nvram_read(nvram, addr) << 8;
  1273 + tmp |= nvram_read(nvram, addr + 1);
  1274 +
1265 return tmp; 1275 return tmp;
1266 } 1276 }
1267 1277
1268 -void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) 1278 +void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
1269 { 1279 {
1270 - m48t59_write(nvram, addr, value >> 24);  
1271 - m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);  
1272 - m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);  
1273 - m48t59_write(nvram, addr + 3, value & 0xFF); 1280 + nvram_write(nvram, addr, value >> 24);
  1281 + nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
  1282 + nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
  1283 + nvram_write(nvram, addr + 3, value & 0xFF);
1274 } 1284 }
1275 1285
1276 -uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr) 1286 +uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
1277 { 1287 {
1278 uint32_t tmp; 1288 uint32_t tmp;
1279 1289
1280 - tmp = m48t59_read(nvram, addr) << 24;  
1281 - tmp |= m48t59_read(nvram, addr + 1) << 16;  
1282 - tmp |= m48t59_read(nvram, addr + 2) << 8;  
1283 - tmp |= m48t59_read(nvram, addr + 3); 1290 + tmp = nvram_read(nvram, addr) << 24;
  1291 + tmp |= nvram_read(nvram, addr + 1) << 16;
  1292 + tmp |= nvram_read(nvram, addr + 2) << 8;
  1293 + tmp |= nvram_read(nvram, addr + 3);
1284 1294
1285 return tmp; 1295 return tmp;
1286 } 1296 }
1287 1297
1288 -void NVRAM_set_string (m48t59_t *nvram, uint32_t addr, 1298 +void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1289 const unsigned char *str, uint32_t max) 1299 const unsigned char *str, uint32_t max)
1290 { 1300 {
1291 int i; 1301 int i;
1292 1302
1293 for (i = 0; i < max && str[i] != '\0'; i++) { 1303 for (i = 0; i < max && str[i] != '\0'; i++) {
1294 - m48t59_write(nvram, addr + i, str[i]); 1304 + nvram_write(nvram, addr + i, str[i]);
1295 } 1305 }
1296 - m48t59_write(nvram, addr + max - 1, '\0'); 1306 + nvram_write(nvram, addr + i, str[i]);
  1307 + nvram_write(nvram, addr + max - 1, '\0');
1297 } 1308 }
1298 1309
1299 -int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max) 1310 +int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
1300 { 1311 {
1301 int i; 1312 int i;
1302 1313
@@ -1325,7 +1336,7 @@ static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value) @@ -1325,7 +1336,7 @@ static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1325 return tmp; 1336 return tmp;
1326 } 1337 }
1327 1338
1328 -uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) 1339 +uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
1329 { 1340 {
1330 uint32_t i; 1341 uint32_t i;
1331 uint16_t crc = 0xFFFF; 1342 uint16_t crc = 0xFFFF;
@@ -1345,7 +1356,7 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) @@ -1345,7 +1356,7 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
1345 1356
1346 #define CMDLINE_ADDR 0x017ff000 1357 #define CMDLINE_ADDR 0x017ff000
1347 1358
1348 -int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, 1359 +int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1349 const unsigned char *arch, 1360 const unsigned char *arch,
1350 uint32_t RAM_size, int boot_device, 1361 uint32_t RAM_size, int boot_device,
1351 uint32_t kernel_image, uint32_t kernel_size, 1362 uint32_t kernel_image, uint32_t kernel_size,
@@ -1382,7 +1393,7 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, @@ -1382,7 +1393,7 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
1382 NVRAM_set_word(nvram, 0x56, height); 1393 NVRAM_set_word(nvram, 0x56, height);
1383 NVRAM_set_word(nvram, 0x58, depth); 1394 NVRAM_set_word(nvram, 0x58, depth);
1384 crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); 1395 crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1385 - NVRAM_set_word(nvram, 0xFC, crc); 1396 + NVRAM_set_word(nvram, 0xFC, crc);
1386 1397
1387 return 0; 1398 return 0;
1388 } 1399 }
hw/ppc_chrp.c
1 /* 1 /*
2 - * QEMU PPC CHRP/PMAC hardware System Emulator 2 + * QEMU PowerPC CHRP (currently NewWorld PowerMac) hardware System Emulator
3 * 3 *
4 * Copyright (c) 2004-2007 Fabrice Bellard 4 * Copyright (c) 2004-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
5 * 6 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 8 * of this software and associated documentation files (the "Software"), to deal
@@ -22,171 +23,7 @@ @@ -22,171 +23,7 @@
22 * THE SOFTWARE. 23 * THE SOFTWARE.
23 */ 24 */
24 #include "vl.h" 25 #include "vl.h"
25 -  
26 -/* SMP is not enabled, for now */  
27 -#define MAX_CPUS 1  
28 -  
29 -#define BIOS_FILENAME "ppc_rom.bin"  
30 -#define VGABIOS_FILENAME "video.x"  
31 -#define NVRAM_SIZE 0x2000  
32 -  
33 -#define KERNEL_LOAD_ADDR 0x01000000  
34 -#define INITRD_LOAD_ADDR 0x01800000  
35 -  
36 -/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,  
37 - NVRAM */  
38 -  
39 -static int dbdma_mem_index;  
40 -static int cuda_mem_index;  
41 -static int ide0_mem_index = -1;  
42 -static int ide1_mem_index = -1;  
43 -static int openpic_mem_index = -1;  
44 -static int heathrow_pic_mem_index = -1;  
45 -static int macio_nvram_mem_index = -1;  
46 -  
47 -/* DBDMA: currently no op - should suffice right now */  
48 -  
49 -static void dbdma_writeb (void *opaque,  
50 - target_phys_addr_t addr, uint32_t value)  
51 -{  
52 - printf("%s: 0x" PADDRX " <= 0x%08x\n", __func__, addr, value);  
53 -}  
54 -  
55 -static void dbdma_writew (void *opaque,  
56 - target_phys_addr_t addr, uint32_t value)  
57 -{  
58 -}  
59 -  
60 -static void dbdma_writel (void *opaque,  
61 - target_phys_addr_t addr, uint32_t value)  
62 -{  
63 -}  
64 -  
65 -static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)  
66 -{  
67 - printf("%s: 0x" PADDRX " => 0x00000000\n", __func__, addr);  
68 -  
69 - return 0;  
70 -}  
71 -  
72 -static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)  
73 -{  
74 - return 0;  
75 -}  
76 -  
77 -static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)  
78 -{  
79 - return 0;  
80 -}  
81 -  
82 -static CPUWriteMemoryFunc *dbdma_write[] = {  
83 - &dbdma_writeb,  
84 - &dbdma_writew,  
85 - &dbdma_writel,  
86 -};  
87 -  
88 -static CPUReadMemoryFunc *dbdma_read[] = {  
89 - &dbdma_readb,  
90 - &dbdma_readw,  
91 - &dbdma_readl,  
92 -};  
93 -  
94 -/* macio style NVRAM device */  
95 -typedef struct MacIONVRAMState {  
96 - uint8_t data[0x2000];  
97 -} MacIONVRAMState;  
98 -  
99 -static void macio_nvram_writeb (void *opaque,  
100 - target_phys_addr_t addr, uint32_t value)  
101 -{  
102 - MacIONVRAMState *s = opaque;  
103 - addr = (addr >> 4) & 0x1fff;  
104 - s->data[addr] = value;  
105 - // printf("macio_nvram_writeb %04x = %02x\n", addr, value);  
106 -}  
107 -  
108 -static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)  
109 -{  
110 - MacIONVRAMState *s = opaque;  
111 - uint32_t value;  
112 -  
113 - addr = (addr >> 4) & 0x1fff;  
114 - value = s->data[addr];  
115 - // printf("macio_nvram_readb %04x = %02x\n", addr, value);  
116 -  
117 - return value;  
118 -}  
119 -  
120 -static CPUWriteMemoryFunc *macio_nvram_write[] = {  
121 - &macio_nvram_writeb,  
122 - &macio_nvram_writeb,  
123 - &macio_nvram_writeb,  
124 -};  
125 -  
126 -static CPUReadMemoryFunc *macio_nvram_read[] = {  
127 - &macio_nvram_readb,  
128 - &macio_nvram_readb,  
129 - &macio_nvram_readb,  
130 -};  
131 -  
132 -static MacIONVRAMState *macio_nvram_init (void)  
133 -{  
134 - MacIONVRAMState *s;  
135 - s = qemu_mallocz(sizeof(MacIONVRAMState));  
136 - if (!s)  
137 - return NULL;  
138 - macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read,  
139 - macio_nvram_write, s);  
140 -  
141 - return s;  
142 -}  
143 -  
144 -static void macio_map (PCIDevice *pci_dev, int region_num,  
145 - uint32_t addr, uint32_t size, int type)  
146 -{  
147 - if (heathrow_pic_mem_index >= 0) {  
148 - cpu_register_physical_memory(addr + 0x00000, 0x1000,  
149 - heathrow_pic_mem_index);  
150 - }  
151 - cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);  
152 - cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);  
153 - if (ide0_mem_index >= 0)  
154 - cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index);  
155 - if (ide1_mem_index >= 0)  
156 - cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);  
157 - if (openpic_mem_index >= 0) {  
158 - cpu_register_physical_memory(addr + 0x40000, 0x40000,  
159 - openpic_mem_index);  
160 - }  
161 - if (macio_nvram_mem_index >= 0)  
162 - cpu_register_physical_memory(addr + 0x60000, 0x20000,  
163 - macio_nvram_mem_index);  
164 -}  
165 -  
166 -static void macio_init (PCIBus *bus, int device_id)  
167 -{  
168 - PCIDevice *d;  
169 -  
170 - d = pci_register_device(bus, "macio", sizeof(PCIDevice),  
171 - -1, NULL, NULL);  
172 - /* Note: this code is strongly inspirated from the corresponding code  
173 - in PearPC */  
174 - d->config[0x00] = 0x6b; // vendor_id  
175 - d->config[0x01] = 0x10;  
176 - d->config[0x02] = device_id;  
177 - d->config[0x03] = device_id >> 8;  
178 -  
179 - d->config[0x0a] = 0x00; // class_sub = pci2pci  
180 - d->config[0x0b] = 0xff; // class_base = bridge  
181 - d->config[0x0e] = 0x00; // header_type  
182 -  
183 - d->config[0x3d] = 0x01; // interrupt on pin 1  
184 -  
185 - dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);  
186 -  
187 - pci_register_io_region(d, 0, 0x80000,  
188 - PCI_ADDRESS_SPACE_MEM, macio_map);  
189 -} 26 +#include "ppc_mac.h"
190 27
191 /* UniN device */ 28 /* UniN device */
192 static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) 29 static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
@@ -210,118 +47,34 @@ static CPUReadMemoryFunc *unin_read[] = { @@ -210,118 +47,34 @@ static CPUReadMemoryFunc *unin_read[] = {
210 &unin_readl, 47 &unin_readl,
211 }; 48 };
212 49
213 -/* temporary frame buffer OSI calls for the video.x driver. The right  
214 - solution is to modify the driver to use VGA PCI I/Os */  
215 -/* XXX: to be removed. This is no way related to emulation */  
216 -static int vga_osi_call (CPUState *env)  
217 -{  
218 - static int vga_vbl_enabled;  
219 - int linesize;  
220 -  
221 - // printf("osi_call R5=%d\n", env->gpr[5]);  
222 -  
223 - /* same handler as PearPC, coming from the original MOL video  
224 - driver. */  
225 - switch(env->gpr[5]) {  
226 - case 4:  
227 - break;  
228 - case 28: /* set_vmode */  
229 - if (env->gpr[6] != 1 || env->gpr[7] != 0)  
230 - env->gpr[3] = 1;  
231 - else  
232 - env->gpr[3] = 0;  
233 - break;  
234 - case 29: /* get_vmode_info */  
235 - if (env->gpr[6] != 0) {  
236 - if (env->gpr[6] != 1 || env->gpr[7] != 0) {  
237 - env->gpr[3] = 1;  
238 - break;  
239 - }  
240 - }  
241 - env->gpr[3] = 0;  
242 - env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */  
243 - env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */  
244 - env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */  
245 - env->gpr[7] = 85 << 16; /* refresh rate */  
246 - env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */  
247 - linesize = ((graphic_depth + 7) >> 3) * graphic_width;  
248 - linesize = (linesize + 3) & ~3;  
249 - env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */  
250 - break;  
251 - case 31: /* set_video power */  
252 - env->gpr[3] = 0;  
253 - break;  
254 - case 39: /* video_ctrl */  
255 - if (env->gpr[6] == 0 || env->gpr[6] == 1)  
256 - vga_vbl_enabled = env->gpr[6];  
257 - env->gpr[3] = 0;  
258 - break;  
259 - case 47:  
260 - break;  
261 - case 59: /* set_color */  
262 - /* R6 = index, R7 = RGB */  
263 - env->gpr[3] = 0;  
264 - break;  
265 - case 64: /* get color */  
266 - /* R6 = index */  
267 - env->gpr[3] = 0;  
268 - break;  
269 - case 116: /* set hwcursor */  
270 - /* R6 = x, R7 = y, R8 = visible, R9 = data */  
271 - break;  
272 - default:  
273 - fprintf(stderr, "unsupported OSI call R5=" REGX "\n", env->gpr[5]);  
274 - break;  
275 - }  
276 -  
277 - return 1; /* osi_call handled */  
278 -}  
279 -  
280 -static uint8_t nvram_chksum (const uint8_t *buf, int n)  
281 -{  
282 - int sum, i;  
283 - sum = 0;  
284 - for(i = 0; i < n; i++)  
285 - sum += buf[i];  
286 - return (sum & 0xff) + (sum >> 8);  
287 -}  
288 -  
289 -/* set a free Mac OS NVRAM partition */  
290 -void pmac_format_nvram_partition (uint8_t *buf, int len)  
291 -{  
292 - char partition_name[12] = "wwwwwwwwwwww";  
293 -  
294 - buf[0] = 0x7f; /* free partition magic */  
295 - buf[1] = 0; /* checksum */  
296 - buf[2] = len >> 8;  
297 - buf[3] = len;  
298 - memcpy(buf + 4, partition_name, 12);  
299 - buf[1] = nvram_chksum(buf, 16);  
300 -}  
301 -  
302 -/* PowerPC CHRP hardware initialisation */  
303 -static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,  
304 - DisplayState *ds, const char **fd_filename,  
305 - int snapshot,  
306 - const char *kernel_filename,  
307 - const char *kernel_cmdline,  
308 - const char *initrd_filename,  
309 - const char *cpu_model,  
310 - int is_heathrow) 50 +/* PowerPC Mac99 hardware initialisation */
  51 +static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device,
  52 + DisplayState *ds, const char **fd_filename,
  53 + int snapshot,
  54 + const char *kernel_filename,
  55 + const char *kernel_cmdline,
  56 + const char *initrd_filename,
  57 + const char *cpu_model)
311 { 58 {
312 CPUState *env, *envs[MAX_CPUS]; 59 CPUState *env, *envs[MAX_CPUS];
313 char buf[1024]; 60 char buf[1024];
314 qemu_irq *pic, **openpic_irqs; 61 qemu_irq *pic, **openpic_irqs;
315 - m48t59_t *nvram;  
316 int unin_memory; 62 int unin_memory;
317 int linux_boot, i; 63 int linux_boot, i;
318 unsigned long bios_offset, vga_bios_offset; 64 unsigned long bios_offset, vga_bios_offset;
319 uint32_t kernel_base, kernel_size, initrd_base, initrd_size; 65 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
320 ppc_def_t *def; 66 ppc_def_t *def;
321 PCIBus *pci_bus; 67 PCIBus *pci_bus;
322 - const char *arch_name; 68 + nvram_t nvram;
  69 +#if 0
  70 + MacIONVRAMState *nvr;
  71 + int nvram_mem_index;
  72 +#endif
  73 + m48t59_t *m48t59;
323 int vga_bios_size, bios_size; 74 int vga_bios_size, bios_size;
324 qemu_irq *dummy_irq; 75 qemu_irq *dummy_irq;
  76 + int pic_mem_index, dbdma_mem_index, cuda_mem_index;
  77 + int ide_mem_index[2];
325 78
326 linux_boot = (kernel_filename != NULL); 79 linux_boot = (kernel_filename != NULL);
327 80
@@ -338,7 +91,9 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -338,7 +91,9 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
338 cpu_ppc_reset(env); 91 cpu_ppc_reset(env);
339 /* Set time-base frequency to 100 Mhz */ 92 /* Set time-base frequency to 100 Mhz */
340 cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); 93 cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
  94 +#if 0
341 env->osi_call = vga_osi_call; 95 env->osi_call = vga_osi_call;
  96 +#endif
342 qemu_register_reset(&cpu_ppc_reset, env); 97 qemu_register_reset(&cpu_ppc_reset, env);
343 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); 98 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
344 envs[i] = env; 99 envs[i] = env;
@@ -413,143 +168,91 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -413,143 +168,91 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
413 initrd_size = 0; 168 initrd_size = 0;
414 } 169 }
415 170
416 - if (is_heathrow) {  
417 - isa_mem_base = 0x80000000;  
418 -  
419 - /* Register 2 MB of ISA IO space */  
420 - isa_mmio_init(0xfe000000, 0x00200000); 171 + isa_mem_base = 0x80000000;
421 172
422 - /* init basic PC hardware */  
423 - if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {  
424 - cpu_abort(env, "Only 6xx bus is supported on heathrow machine\n");  
425 - exit(1);  
426 - }  
427 - pic = heathrow_pic_init(&heathrow_pic_mem_index);  
428 - pci_bus = pci_grackle_init(0xfec00000, pic);  
429 - pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,  
430 - ram_size, vga_ram_size,  
431 - vga_bios_offset, vga_bios_size);  
432 -  
433 - /* XXX: suppress that */  
434 - dummy_irq = i8259_init(NULL);  
435 -  
436 - /* XXX: use Mac Serial port */  
437 - serial_init(0x3f8, dummy_irq[4], serial_hds[0]);  
438 -  
439 - for(i = 0; i < nb_nics; i++) {  
440 - if (!nd_table[i].model)  
441 - nd_table[i].model = "ne2k_pci";  
442 - pci_nic_init(pci_bus, &nd_table[i], -1);  
443 - } 173 + /* Register 8 MB of ISA IO space */
  174 + isa_mmio_init(0xf2000000, 0x00800000);
444 175
445 - pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);  
446 -  
447 - /* cuda also initialize ADB */  
448 - cuda_mem_index = cuda_init(pic[0x12]);  
449 -  
450 - adb_kbd_init(&adb_bus);  
451 - adb_mouse_init(&adb_bus);  
452 -  
453 - {  
454 - MacIONVRAMState *nvr;  
455 - nvr = macio_nvram_init();  
456 - pmac_format_nvram_partition(nvr->data, 0x2000);  
457 - }  
458 -  
459 - macio_init(pci_bus, 0x0017);  
460 -  
461 - nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);  
462 -  
463 - arch_name = "HEATHROW";  
464 - } else {  
465 - isa_mem_base = 0x80000000; 176 + /* UniN init */
  177 + unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
  178 + cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
466 179
467 - /* Register 8 MB of ISA IO space */  
468 - isa_mmio_init(0xf2000000, 0x00800000);  
469 -  
470 - /* UniN init */  
471 - unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);  
472 - cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);  
473 -  
474 - openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));  
475 - openpic_irqs[0] =  
476 - qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);  
477 - for (i = 0; i < smp_cpus; i++) {  
478 - /* Mac99 IRQ connection between OpenPIC outputs pins  
479 - * and PowerPC input pins  
480 - */  
481 - switch (PPC_INPUT(env)) {  
482 - case PPC_FLAGS_INPUT_6xx:  
483 - openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);  
484 - openpic_irqs[i][OPENPIC_OUTPUT_INT] =  
485 - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];  
486 - openpic_irqs[i][OPENPIC_OUTPUT_CINT] =  
487 - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];  
488 - openpic_irqs[i][OPENPIC_OUTPUT_MCK] =  
489 - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];  
490 - /* Not connected ? */  
491 - openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;  
492 - /* Check this */  
493 - openpic_irqs[i][OPENPIC_OUTPUT_RESET] =  
494 - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];  
495 - break; 180 + openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
  181 + openpic_irqs[0] =
  182 + qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
  183 + for (i = 0; i < smp_cpus; i++) {
  184 + /* Mac99 IRQ connection between OpenPIC outputs pins
  185 + * and PowerPC input pins
  186 + */
  187 + switch (PPC_INPUT(env)) {
  188 + case PPC_FLAGS_INPUT_6xx:
  189 + openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
  190 + openpic_irqs[i][OPENPIC_OUTPUT_INT] =
  191 + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
  192 + openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
  193 + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
  194 + openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
  195 + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
  196 + /* Not connected ? */
  197 + openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
  198 + /* Check this */
  199 + openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
  200 + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
  201 + break;
496 #if defined(TARGET_PPC64) 202 #if defined(TARGET_PPC64)
497 - case PPC_FLAGS_INPUT_970:  
498 - openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);  
499 - openpic_irqs[i][OPENPIC_OUTPUT_INT] =  
500 - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];  
501 - openpic_irqs[i][OPENPIC_OUTPUT_CINT] =  
502 - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];  
503 - openpic_irqs[i][OPENPIC_OUTPUT_MCK] =  
504 - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];  
505 - /* Not connected ? */  
506 - openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;  
507 - /* Check this */  
508 - openpic_irqs[i][OPENPIC_OUTPUT_RESET] =  
509 - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];  
510 - break; 203 + case PPC_FLAGS_INPUT_970:
  204 + openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
  205 + openpic_irqs[i][OPENPIC_OUTPUT_INT] =
  206 + ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
  207 + openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
  208 + ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
  209 + openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
  210 + ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
  211 + /* Not connected ? */
  212 + openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
  213 + /* Check this */
  214 + openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
  215 + ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
  216 + break;
511 #endif /* defined(TARGET_PPC64) */ 217 #endif /* defined(TARGET_PPC64) */
512 - default:  
513 - cpu_abort(env, "Bus model not supported on mac99 machine\n");  
514 - exit(1);  
515 - }  
516 - }  
517 - pic = openpic_init(NULL, &openpic_mem_index, smp_cpus,  
518 - openpic_irqs, NULL);  
519 - pci_bus = pci_pmac_init(pic);  
520 - /* init basic PC hardware */  
521 - pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,  
522 - ram_size, vga_ram_size,  
523 - vga_bios_offset, vga_bios_size);  
524 -  
525 - /* XXX: suppress that */  
526 - dummy_irq = i8259_init(NULL);  
527 -  
528 - /* XXX: use Mac Serial port */  
529 - serial_init(0x3f8, dummy_irq[4], serial_hds[0]);  
530 - for(i = 0; i < nb_nics; i++) {  
531 - if (!nd_table[i].model)  
532 - nd_table[i].model = "ne2k_pci";  
533 - pci_nic_init(pci_bus, &nd_table[i], -1); 218 + default:
  219 + cpu_abort(env, "Bus model not supported on mac99 machine\n");
  220 + exit(1);
534 } 221 }
  222 + }
  223 + pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
  224 + pci_bus = pci_pmac_init(pic);
  225 + /* init basic PC hardware */
  226 + pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
  227 + ram_size, vga_ram_size,
  228 + vga_bios_offset, vga_bios_size);
  229 +
  230 + /* XXX: suppress that */
  231 + dummy_irq = i8259_init(NULL);
  232 +
  233 + /* XXX: use Mac Serial port */
  234 + serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
  235 + for(i = 0; i < nb_nics; i++) {
  236 + if (!nd_table[i].model)
  237 + nd_table[i].model = "ne2k_pci";
  238 + pci_nic_init(pci_bus, &nd_table[i], -1);
  239 + }
535 #if 1 240 #if 1
536 - ide0_mem_index = pmac_ide_init(&bs_table[0], pic[0x13]);  
537 - ide1_mem_index = pmac_ide_init(&bs_table[2], pic[0x14]); 241 + ide_mem_index[0] = pmac_ide_init(&bs_table[0], pic[0x13]);
  242 + ide_mem_index[1] = pmac_ide_init(&bs_table[2], pic[0x14]);
538 #else 243 #else
539 - pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); 244 + pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
540 #endif 245 #endif
541 - /* cuda also initialize ADB */  
542 - cuda_mem_index = cuda_init(pic[0x19]);  
543 -  
544 - adb_kbd_init(&adb_bus);  
545 - adb_mouse_init(&adb_bus);  
546 -  
547 - macio_init(pci_bus, 0x0022); 246 + /* cuda also initialize ADB */
  247 + cuda_init(&cuda_mem_index, pic[0x19]);
  248 +
  249 + adb_kbd_init(&adb_bus);
  250 + adb_mouse_init(&adb_bus);
548 251
549 - nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59); 252 + dbdma_init(&dbdma_mem_index);
550 253
551 - arch_name = "MAC99";  
552 - } 254 + macio_init(pci_bus, 0x0022, 0, pic_mem_index, dbdma_mem_index,
  255 + cuda_mem_index, -1, 2, ide_mem_index);
553 256
554 if (usb_enabled) { 257 if (usb_enabled) {
555 usb_ohci_init_pci(pci_bus, 3, -1); 258 usb_ohci_init_pci(pci_bus, 3, -1);
@@ -557,8 +260,21 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -557,8 +260,21 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
557 260
558 if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) 261 if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
559 graphic_depth = 15; 262 graphic_depth = 15;
560 -  
561 - PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, boot_device, 263 +#if 0 /* XXX: this is ugly but needed for now, or OHW won't boot */
  264 + /* The NewWorld NVRAM is not located in the MacIO device */
  265 + nvr = macio_nvram_init(&nvram_mem_index);
  266 + pmac_format_nvram_partition(nvr, 0x2000);
  267 + cpu_register_physical_memory(0xFFF04000, 0x20000, nvram_mem_index);
  268 + nvram.opaque = nvr;
  269 + nvram.read_fn = &macio_nvram_read;
  270 + nvram.write_fn = &macio_nvram_write;
  271 +#else
  272 + m48t59 = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
  273 + nvram.opaque = m48t59;
  274 + nvram.read_fn = &m48t59_read;
  275 + nvram.write_fn = &m48t59_write;
  276 +#endif
  277 + PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "MAC99", ram_size, boot_device,
562 kernel_base, kernel_size, 278 kernel_base, kernel_size,
563 kernel_cmdline, 279 kernel_cmdline,
564 initrd_base, initrd_size, 280 initrd_base, initrd_size,
@@ -569,44 +285,10 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -569,44 +285,10 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
569 285
570 /* Special port to get debug messages from Open-Firmware */ 286 /* Special port to get debug messages from Open-Firmware */
571 register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL); 287 register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
572 -}  
573 -  
574 -static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device,  
575 - DisplayState *ds, const char **fd_filename,  
576 - int snapshot,  
577 - const char *kernel_filename,  
578 - const char *kernel_cmdline,  
579 - const char *initrd_filename,  
580 - const char *cpu_model)  
581 -{  
582 - ppc_chrp_init(ram_size, vga_ram_size, boot_device,  
583 - ds, fd_filename, snapshot,  
584 - kernel_filename, kernel_cmdline,  
585 - initrd_filename, cpu_model, 0);  
586 -}  
587 -  
588 -static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device,  
589 - DisplayState *ds, const char **fd_filename,  
590 - int snapshot,  
591 - const char *kernel_filename,  
592 - const char *kernel_cmdline,  
593 - const char *initrd_filename,  
594 - const char *cpu_model)  
595 -{  
596 - ppc_chrp_init(ram_size, vga_ram_size, boot_device,  
597 - ds, fd_filename, snapshot,  
598 - kernel_filename, kernel_cmdline,  
599 - initrd_filename, cpu_model, 1);  
600 -} 288 + }
601 289
602 QEMUMachine core99_machine = { 290 QEMUMachine core99_machine = {
603 "mac99", 291 "mac99",
604 "Mac99 based PowerMAC", 292 "Mac99 based PowerMAC",
605 ppc_core99_init, 293 ppc_core99_init,
606 }; 294 };
607 -  
608 -QEMUMachine heathrow_machine = {  
609 - "g3bw",  
610 - "Heathrow based PowerMAC",  
611 - ppc_heathrow_init,  
612 -};  
hw/ppc_mac.h 0 โ†’ 100644
  1 +/*
  2 + * QEMU PowerMac emulation shared definitions and prototypes
  3 + *
  4 + * Copyright (c) 2004-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +#if !defined(__PPC_MAC_H__)
  26 +#define __PPC_MAC_H__
  27 +
  28 +/* SMP is not enabled, for now */
  29 +#define MAX_CPUS 1
  30 +
  31 +#define BIOS_FILENAME "ppc_rom.bin"
  32 +#define VGABIOS_FILENAME "video.x"
  33 +#define NVRAM_SIZE 0x2000
  34 +
  35 +#define KERNEL_LOAD_ADDR 0x01000000
  36 +#define INITRD_LOAD_ADDR 0x01800000
  37 +
  38 +/* DBDMA */
  39 +void dbdma_init (int *dbdma_mem_index);
  40 +
  41 +/* Cuda */
  42 +void cuda_init (int *cuda_mem_index, qemu_irq irq);
  43 +
  44 +/* MacIO */
  45 +void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
  46 + int dbdma_mem_index, int cuda_mem_index, int nvram_mem_index,
  47 + int nb_ide, int *ide_mem_index);
  48 +
  49 +/* NewWorld PowerMac IDE */
  50 +int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq);
  51 +
  52 +/* Heathrow PIC */
  53 +qemu_irq *heathrow_pic_init(int *pmem_index,
  54 + int nb_cpus, qemu_irq **irqs);
  55 +
  56 +/* Grackle PCI */
  57 +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);
  58 +
  59 +/* UniNorth PCI */
  60 +PCIBus *pci_pmac_init(qemu_irq *pic);
  61 +
  62 +/* Mac NVRAM */
  63 +typedef struct MacIONVRAMState MacIONVRAMState;
  64 +
  65 +MacIONVRAMState *macio_nvram_init (int *mem_index);
  66 +void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
  67 +uint32_t macio_nvram_read (void *opaque, uint32_t addr);
  68 +void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
  69 +
  70 +#endif /* !defined(__PPC_MAC_H__) */
hw/ppc_oldworld.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU OldWorld PowerMac (currently ~G3 B&W) hardware System Emulator
  3 + *
  4 + * Copyright (c) 2004-2007 Fabrice Bellard
  5 + * Copyright (c) 2007 Jocelyn Mayer
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +#include "vl.h"
  26 +#include "ppc_mac.h"
  27 +
  28 +/* temporary frame buffer OSI calls for the video.x driver. The right
  29 + solution is to modify the driver to use VGA PCI I/Os */
  30 +/* XXX: to be removed. This is no way related to emulation */
  31 +static int vga_osi_call (CPUState *env)
  32 +{
  33 + static int vga_vbl_enabled;
  34 + int linesize;
  35 +
  36 + // printf("osi_call R5=%d\n", env->gpr[5]);
  37 +
  38 + /* same handler as PearPC, coming from the original MOL video
  39 + driver. */
  40 + switch(env->gpr[5]) {
  41 + case 4:
  42 + break;
  43 + case 28: /* set_vmode */
  44 + if (env->gpr[6] != 1 || env->gpr[7] != 0)
  45 + env->gpr[3] = 1;
  46 + else
  47 + env->gpr[3] = 0;
  48 + break;
  49 + case 29: /* get_vmode_info */
  50 + if (env->gpr[6] != 0) {
  51 + if (env->gpr[6] != 1 || env->gpr[7] != 0) {
  52 + env->gpr[3] = 1;
  53 + break;
  54 + }
  55 + }
  56 + env->gpr[3] = 0;
  57 + env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
  58 + env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
  59 + env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
  60 + env->gpr[7] = 85 << 16; /* refresh rate */
  61 + env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */
  62 + linesize = ((graphic_depth + 7) >> 3) * graphic_width;
  63 + linesize = (linesize + 3) & ~3;
  64 + env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */
  65 + break;
  66 + case 31: /* set_video power */
  67 + env->gpr[3] = 0;
  68 + break;
  69 + case 39: /* video_ctrl */
  70 + if (env->gpr[6] == 0 || env->gpr[6] == 1)
  71 + vga_vbl_enabled = env->gpr[6];
  72 + env->gpr[3] = 0;
  73 + break;
  74 + case 47:
  75 + break;
  76 + case 59: /* set_color */
  77 + /* R6 = index, R7 = RGB */
  78 + env->gpr[3] = 0;
  79 + break;
  80 + case 64: /* get color */
  81 + /* R6 = index */
  82 + env->gpr[3] = 0;
  83 + break;
  84 + case 116: /* set hwcursor */
  85 + /* R6 = x, R7 = y, R8 = visible, R9 = data */
  86 + break;
  87 + default:
  88 + fprintf(stderr, "unsupported OSI call R5=" REGX "\n", env->gpr[5]);
  89 + break;
  90 + }
  91 +
  92 + return 1; /* osi_call handled */
  93 +}
  94 +
  95 +static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device,
  96 + DisplayState *ds, const char **fd_filename,
  97 + int snapshot,
  98 + const char *kernel_filename,
  99 + const char *kernel_cmdline,
  100 + const char *initrd_filename,
  101 + const char *cpu_model)
  102 +{
  103 + CPUState *env, *envs[MAX_CPUS];
  104 + char buf[1024];
  105 + qemu_irq *pic, **heathrow_irqs;
  106 + nvram_t nvram;
  107 + m48t59_t *m48t59;
  108 + int linux_boot, i;
  109 + unsigned long bios_offset, vga_bios_offset;
  110 + uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  111 + ppc_def_t *def;
  112 + PCIBus *pci_bus;
  113 + MacIONVRAMState *nvr;
  114 + int vga_bios_size, bios_size;
  115 + qemu_irq *dummy_irq;
  116 + int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
  117 +
  118 + linux_boot = (kernel_filename != NULL);
  119 +
  120 + /* init CPUs */
  121 + env = cpu_init();
  122 + if (cpu_model == NULL)
  123 + cpu_model = "default";
  124 + ppc_find_by_name(cpu_model, &def);
  125 + if (def == NULL) {
  126 + cpu_abort(env, "Unable to find PowerPC CPU definition\n");
  127 + }
  128 + for (i = 0; i < smp_cpus; i++) {
  129 + cpu_ppc_register(env, def);
  130 + cpu_ppc_reset(env);
  131 + /* Set time-base frequency to 100 Mhz */
  132 + cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
  133 + env->osi_call = vga_osi_call;
  134 + qemu_register_reset(&cpu_ppc_reset, env);
  135 + register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
  136 + envs[i] = env;
  137 + }
  138 +
  139 + /* allocate RAM */
  140 + cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
  141 +
  142 + /* allocate and load BIOS */
  143 + bios_offset = ram_size + vga_ram_size;
  144 + if (bios_name == NULL)
  145 + bios_name = BIOS_FILENAME;
  146 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
  147 + bios_size = load_image(buf, phys_ram_base + bios_offset);
  148 + if (bios_size < 0 || bios_size > BIOS_SIZE) {
  149 + cpu_abort(env, "qemu: could not load PowerPC bios '%s'\n", buf);
  150 + exit(1);
  151 + }
  152 + bios_size = (bios_size + 0xfff) & ~0xfff;
  153 + cpu_register_physical_memory((uint32_t)(-bios_size),
  154 + bios_size, bios_offset | IO_MEM_ROM);
  155 +
  156 + /* allocate and load VGA BIOS */
  157 + vga_bios_offset = bios_offset + bios_size;
  158 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
  159 + vga_bios_size = load_image(buf, phys_ram_base + vga_bios_offset + 8);
  160 + if (vga_bios_size < 0) {
  161 + /* if no bios is present, we can still work */
  162 + fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf);
  163 + vga_bios_size = 0;
  164 + } else {
  165 + /* set a specific header (XXX: find real Apple format for NDRV
  166 + drivers) */
  167 + phys_ram_base[vga_bios_offset] = 'N';
  168 + phys_ram_base[vga_bios_offset + 1] = 'D';
  169 + phys_ram_base[vga_bios_offset + 2] = 'R';
  170 + phys_ram_base[vga_bios_offset + 3] = 'V';
  171 + cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4),
  172 + vga_bios_size);
  173 + vga_bios_size += 8;
  174 + }
  175 + vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff;
  176 +
  177 + if (linux_boot) {
  178 + kernel_base = KERNEL_LOAD_ADDR;
  179 + /* now we can load the kernel */
  180 + kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
  181 + if (kernel_size < 0) {
  182 + cpu_abort(env, "qemu: could not load kernel '%s'\n",
  183 + kernel_filename);
  184 + exit(1);
  185 + }
  186 + /* load initrd */
  187 + if (initrd_filename) {
  188 + initrd_base = INITRD_LOAD_ADDR;
  189 + initrd_size = load_image(initrd_filename,
  190 + phys_ram_base + initrd_base);
  191 + if (initrd_size < 0) {
  192 + cpu_abort(env, "qemu: could not load initial ram disk '%s'\n",
  193 + initrd_filename);
  194 + exit(1);
  195 + }
  196 + } else {
  197 + initrd_base = 0;
  198 + initrd_size = 0;
  199 + }
  200 + boot_device = 'm';
  201 + } else {
  202 + kernel_base = 0;
  203 + kernel_size = 0;
  204 + initrd_base = 0;
  205 + initrd_size = 0;
  206 + }
  207 +
  208 + isa_mem_base = 0x80000000;
  209 +
  210 + /* Register 2 MB of ISA IO space */
  211 + isa_mmio_init(0xfe000000, 0x00200000);
  212 +
  213 + /* XXX: we register only 1 output pin for heathrow PIC */
  214 + heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
  215 + heathrow_irqs[0] =
  216 + qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1);
  217 + /* Connect the heathrow PIC outputs to the 6xx bus */
  218 + for (i = 0; i < smp_cpus; i++) {
  219 + switch (PPC_INPUT(env)) {
  220 + case PPC_FLAGS_INPUT_6xx:
  221 + heathrow_irqs[i] = heathrow_irqs[0] + (i * 1);
  222 + heathrow_irqs[i][0] =
  223 + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
  224 + break;
  225 + default:
  226 + cpu_abort(env, "Bus model not supported on OldWorld Mac machine\n");
  227 + exit(1);
  228 + }
  229 + }
  230 +
  231 + /* init basic PC hardware */
  232 + if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
  233 + cpu_abort(env, "Only 6xx bus is supported on heathrow machine\n");
  234 + exit(1);
  235 + }
  236 + pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
  237 + pci_bus = pci_grackle_init(0xfec00000, pic);
  238 + pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
  239 + ram_size, vga_ram_size,
  240 + vga_bios_offset, vga_bios_size);
  241 +
  242 + /* XXX: suppress that */
  243 + dummy_irq = i8259_init(NULL);
  244 +
  245 + /* XXX: use Mac Serial port */
  246 + serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
  247 +
  248 + for(i = 0; i < nb_nics; i++) {
  249 + if (!nd_table[i].model)
  250 + nd_table[i].model = "ne2k_pci";
  251 + pci_nic_init(pci_bus, &nd_table[i], -1);
  252 + }
  253 +
  254 + pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
  255 +
  256 + /* cuda also initialize ADB */
  257 + cuda_init(&cuda_mem_index, pic[0x12]);
  258 +
  259 + adb_kbd_init(&adb_bus);
  260 + adb_mouse_init(&adb_bus);
  261 +
  262 + nvr = macio_nvram_init(&nvram_mem_index);
  263 + pmac_format_nvram_partition(nvr, 0x2000);
  264 +
  265 + dbdma_init(&dbdma_mem_index);
  266 +
  267 + macio_init(pci_bus, 0x0017, 1, pic_mem_index, dbdma_mem_index,
  268 + cuda_mem_index, nvram_mem_index, 0, NULL);
  269 +
  270 + if (usb_enabled) {
  271 + usb_ohci_init_pci(pci_bus, 3, -1);
  272 + }
  273 +
  274 + if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
  275 + graphic_depth = 15;
  276 +
  277 + m48t59 = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
  278 + nvram.opaque = m48t59;
  279 + nvram.read_fn = &m48t59_read;
  280 + nvram.write_fn = &m48t59_write;
  281 + PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "HEATHROW", ram_size, boot_device,
  282 + kernel_base, kernel_size,
  283 + kernel_cmdline,
  284 + initrd_base, initrd_size,
  285 + /* XXX: need an option to load a NVRAM image */
  286 + 0,
  287 + graphic_width, graphic_height, graphic_depth);
  288 + /* No PCI init: the BIOS will do it */
  289 +
  290 + /* Special port to get debug messages from Open-Firmware */
  291 + register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
  292 +}
  293 +
  294 +QEMUMachine heathrow_machine = {
  295 + "g3bw",
  296 + "Heathrow based PowerMAC",
  297 + ppc_heathrow_init,
  298 +};
hw/ppc_prep.c
@@ -527,7 +527,8 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, @@ -527,7 +527,8 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
527 { 527 {
528 CPUState *env, *envs[MAX_CPUS]; 528 CPUState *env, *envs[MAX_CPUS];
529 char buf[1024]; 529 char buf[1024];
530 - m48t59_t *nvram; 530 + nvram_t nvram;
  531 + m48t59_t *m48t59;
531 int PPC_io_memory; 532 int PPC_io_memory;
532 int linux_boot, i, nb_nics1, bios_size; 533 int linux_boot, i, nb_nics1, bios_size;
533 unsigned long bios_offset; 534 unsigned long bios_offset;
@@ -678,13 +679,16 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, @@ -678,13 +679,16 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
678 usb_ohci_init_pci(pci_bus, 3, -1); 679 usb_ohci_init_pci(pci_bus, 3, -1);
679 } 680 }
680 681
681 - nvram = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);  
682 - if (nvram == NULL) 682 + m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
  683 + if (m48t59 == NULL)
683 return; 684 return;
684 - sysctrl->nvram = nvram; 685 + sysctrl->nvram = m48t59;
685 686
686 /* Initialise NVRAM */ 687 /* Initialise NVRAM */
687 - PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device, 688 + nvram.opaque = m48t59;
  689 + nvram.read_fn = &m48t59_read;
  690 + nvram.write_fn = &m48t59_write;
  691 + PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
688 kernel_base, kernel_size, 692 kernel_base, kernel_size,
689 kernel_cmdline, 693 kernel_cmdline,
690 initrd_base, initrd_size, 694 initrd_base, initrd_size,
@@ -859,12 +859,6 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, @@ -859,12 +859,6 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
859 /* prep_pci.c */ 859 /* prep_pci.c */
860 PCIBus *pci_prep_init(qemu_irq *pic); 860 PCIBus *pci_prep_init(qemu_irq *pic);
861 861
862 -/* grackle_pci.c */  
863 -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);  
864 -  
865 -/* unin_pci.c */  
866 -PCIBus *pci_pmac_init(qemu_irq *pic);  
867 -  
868 /* apb_pci.c */ 862 /* apb_pci.c */
869 PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base, 863 PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
870 qemu_irq *pic); 864 qemu_irq *pic);
@@ -892,9 +886,6 @@ enum { @@ -892,9 +886,6 @@ enum {
892 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, 886 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
893 qemu_irq **irqs, qemu_irq irq_out); 887 qemu_irq **irqs, qemu_irq irq_out);
894 888
895 -/* heathrow_pic.c */  
896 -qemu_irq *heathrow_pic_init(int *pmem_index);  
897 -  
898 /* gt64xxx.c */ 889 /* gt64xxx.c */
899 PCIBus *pci_gt64120_init(qemu_irq *pic); 890 PCIBus *pci_gt64120_init(qemu_irq *pic);
900 891
@@ -1004,7 +995,6 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -1004,7 +995,6 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
1004 qemu_irq *pic); 995 qemu_irq *pic);
1005 void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, 996 void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
1006 qemu_irq *pic); 997 qemu_irq *pic);
1007 -int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq);  
1008 998
1009 /* cdrom.c */ 999 /* cdrom.c */
1010 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); 1000 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
@@ -1242,12 +1232,12 @@ clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq); @@ -1242,12 +1232,12 @@ clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq);
1242 void ppc40x_core_reset (CPUState *env); 1232 void ppc40x_core_reset (CPUState *env);
1243 void ppc40x_chip_reset (CPUState *env); 1233 void ppc40x_chip_reset (CPUState *env);
1244 void ppc40x_system_reset (CPUState *env); 1234 void ppc40x_system_reset (CPUState *env);
1245 -#endif  
1246 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val); 1235 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
1247 1236
1248 extern CPUWriteMemoryFunc *PPC_io_write[]; 1237 extern CPUWriteMemoryFunc *PPC_io_write[];
1249 extern CPUReadMemoryFunc *PPC_io_read[]; 1238 extern CPUReadMemoryFunc *PPC_io_read[];
1250 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); 1239 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
  1240 +#endif
1251 1241
1252 /* sun4m.c */ 1242 /* sun4m.c */
1253 extern QEMUMachine ss5_machine, ss10_machine; 1243 extern QEMUMachine ss5_machine, ss10_machine;
@@ -1327,20 +1317,28 @@ void cs_init(target_phys_addr_t base, int irq, void *intctl); @@ -1327,20 +1317,28 @@ void cs_init(target_phys_addr_t base, int irq, void *intctl);
1327 extern QEMUMachine sun4u_machine; 1317 extern QEMUMachine sun4u_machine;
1328 1318
1329 /* NVRAM helpers */ 1319 /* NVRAM helpers */
  1320 +typedef uint32_t (*nvram_read_t)(void *private, uint32_t addr);
  1321 +typedef void (*nvram_write_t)(void *private, uint32_t addr, uint32_t val);
  1322 +typedef struct nvram_t {
  1323 + void *opaque;
  1324 + nvram_read_t read_fn;
  1325 + nvram_write_t write_fn;
  1326 +} nvram_t;
  1327 +
1330 #include "hw/m48t59.h" 1328 #include "hw/m48t59.h"
1331 1329
1332 -void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);  
1333 -uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);  
1334 -void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);  
1335 -uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);  
1336 -void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);  
1337 -uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);  
1338 -void NVRAM_set_string (m48t59_t *nvram, uint32_t addr, 1330 +void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value);
  1331 +uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr);
  1332 +void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value);
  1333 +uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr);
  1334 +void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value);
  1335 +uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr);
  1336 +void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1339 const unsigned char *str, uint32_t max); 1337 const unsigned char *str, uint32_t max);
1340 -int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);  
1341 -void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr, 1338 +int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max);
  1339 +void NVRAM_set_crc (nvram_t *nvram, uint32_t addr,
1342 uint32_t start, uint32_t count); 1340 uint32_t start, uint32_t count);
1343 -int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, 1341 +int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1344 const unsigned char *arch, 1342 const unsigned char *arch,
1345 uint32_t RAM_size, int boot_device, 1343 uint32_t RAM_size, int boot_device,
1346 uint32_t kernel_image, uint32_t kernel_size, 1344 uint32_t kernel_image, uint32_t kernel_size,
@@ -1388,10 +1386,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, @@ -1388,10 +1386,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
1388 void adb_kbd_init(ADBBusState *bus); 1386 void adb_kbd_init(ADBBusState *bus);
1389 void adb_mouse_init(ADBBusState *bus); 1387 void adb_mouse_init(ADBBusState *bus);
1390 1388
1391 -/* cuda.c */  
1392 -  
1393 extern ADBBusState adb_bus; 1389 extern ADBBusState adb_bus;
1394 -int cuda_init(qemu_irq irq);  
1395 1390
1396 #include "hw/usb.h" 1391 #include "hw/usb.h"
1397 1392