Commit 3cbee15b9a6be17645e908bf7706d582c3e17156
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
Showing
13 changed files
with
908 additions
and
512 deletions
Makefile.target
... | ... | @@ -469,13 +469,20 @@ VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmport.o vmware_vga.o |
469 | 469 | CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE |
470 | 470 | endif |
471 | 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 | 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 | 486 | endif |
480 | 487 | ifeq ($(TARGET_BASE_ARCH), mips) |
481 | 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 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 8 | * of this software and associated documentation files (the "Software"), to deal |
... | ... | @@ -22,6 +23,7 @@ |
22 | 23 | * THE SOFTWARE. |
23 | 24 | */ |
24 | 25 | #include "vl.h" |
26 | +#include "ppc_mac.h" | |
25 | 27 | |
26 | 28 | /* XXX: implement all timer modes */ |
27 | 29 | |
... | ... | @@ -634,10 +636,9 @@ static CPUReadMemoryFunc *cuda_read[] = { |
634 | 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 | 641 | CUDAState *s = &cuda_state; |
640 | - int cuda_mem_index; | |
641 | 642 | |
642 | 643 | s->irq = irq; |
643 | 644 | |
... | ... | @@ -653,6 +654,5 @@ int cuda_init(qemu_irq irq) |
653 | 654 | set_counter(s, &s->timers[1], 0xffff); |
654 | 655 | |
655 | 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 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 8 | * of this software and associated documentation files (the "Software"), to deal |
... | ... | @@ -23,6 +24,7 @@ |
23 | 24 | */ |
24 | 25 | |
25 | 26 | #include "vl.h" |
27 | +#include "ppc_mac.h" | |
26 | 28 | typedef target_phys_addr_t pci_addr_t; |
27 | 29 | #include "pci_host.h" |
28 | 30 | |
... | ... | @@ -82,7 +84,7 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num) |
82 | 84 | |
83 | 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 | 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 | 95 | |
94 | 96 | s = qemu_mallocz(sizeof(GrackleState)); |
95 | 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 | 100 | pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, |
99 | 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 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 8 | * of this software and associated documentation files (the "Software"), to deal |
... | ... | @@ -22,6 +23,7 @@ |
22 | 23 | * THE SOFTWARE. |
23 | 24 | */ |
24 | 25 | #include "vl.h" |
26 | +#include "ppc_mac.h" | |
25 | 27 | |
26 | 28 | //#define DEBUG |
27 | 29 | |
... | ... | @@ -34,6 +36,7 @@ typedef struct HeathrowPIC { |
34 | 36 | |
35 | 37 | typedef struct HeathrowPICS { |
36 | 38 | HeathrowPIC pics[2]; |
39 | + qemu_irq *irqs; | |
37 | 40 | } HeathrowPICS; |
38 | 41 | |
39 | 42 | static inline int check_irq(HeathrowPIC *pic) |
... | ... | @@ -45,9 +48,9 @@ static inline int check_irq(HeathrowPIC *pic) |
45 | 48 | static void heathrow_pic_update(HeathrowPICS *s) |
46 | 49 | { |
47 | 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 | 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 | 60 | HeathrowPIC *pic; |
58 | 61 | unsigned int n; |
59 | 62 | |
63 | +#ifdef TARGET_WORDS_BIGENDIAN | |
60 | 64 | value = bswap32(value); |
61 | -#ifdef DEBUG | |
62 | - printf("pic_writel: %08x: %08x\n", | |
63 | - addr, value); | |
64 | 65 | #endif |
65 | 66 | n = ((addr & 0xfff) - 0x10) >> 4; |
67 | +#ifdef DEBUG | |
68 | + printf("pic_writel: " PADDRX " %u: %08x\n", addr, n, value); | |
69 | +#endif | |
66 | 70 | if (n >= 2) |
67 | 71 | return; |
68 | 72 | pic = &s->pics[n]; |
... | ... | @@ -110,10 +114,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) |
110 | 114 | } |
111 | 115 | } |
112 | 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 | 118 | #endif |
119 | +#ifdef TARGET_WORDS_BIGENDIAN | |
116 | 120 | value = bswap32(value); |
121 | +#endif | |
117 | 122 | return value; |
118 | 123 | } |
119 | 124 | |
... | ... | @@ -156,13 +161,17 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level) |
156 | 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 | 167 | HeathrowPICS *s; |
162 | 168 | |
163 | 169 | s = qemu_mallocz(sizeof(HeathrowPICS)); |
164 | 170 | s->pics[0].level_triggered = 0; |
165 | 171 | s->pics[1].level_triggered = 0x1ff00000; |
172 | + /* only 1 CPU */ | |
173 | + s->irqs = irqs[0]; | |
166 | 174 | *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s); |
175 | + | |
167 | 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 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | -#include "m48t59.h" | |
26 | 25 | |
27 | 26 | //#define PPC_DEBUG_IRQ |
28 | 27 | //#define PPC_DEBUG_TB |
... | ... | @@ -1240,63 +1239,75 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val) |
1240 | 1239 | |
1241 | 1240 | /*****************************************************************************/ |
1242 | 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 | 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 | 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 | 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 | 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 | 1299 | const unsigned char *str, uint32_t max) |
1290 | 1300 | { |
1291 | 1301 | int i; |
1292 | 1302 | |
1293 | 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 | 1312 | int i; |
1302 | 1313 | |
... | ... | @@ -1325,7 +1336,7 @@ static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value) |
1325 | 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 | 1341 | uint32_t i; |
1331 | 1342 | uint16_t crc = 0xFFFF; |
... | ... | @@ -1345,7 +1356,7 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) |
1345 | 1356 | |
1346 | 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 | 1360 | const unsigned char *arch, |
1350 | 1361 | uint32_t RAM_size, int boot_device, |
1351 | 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 | 1393 | NVRAM_set_word(nvram, 0x56, height); |
1383 | 1394 | NVRAM_set_word(nvram, 0x58, depth); |
1384 | 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 | 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 | 4 | * Copyright (c) 2004-2007 Fabrice Bellard |
5 | + * Copyright (c) 2007 Jocelyn Mayer | |
5 | 6 | * |
6 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 8 | * of this software and associated documentation files (the "Software"), to deal |
... | ... | @@ -22,171 +23,7 @@ |
22 | 23 | * THE SOFTWARE. |
23 | 24 | */ |
24 | 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 | 28 | /* UniN device */ |
192 | 29 | static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
... | ... | @@ -210,118 +47,34 @@ static CPUReadMemoryFunc *unin_read[] = { |
210 | 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 | 59 | CPUState *env, *envs[MAX_CPUS]; |
313 | 60 | char buf[1024]; |
314 | 61 | qemu_irq *pic, **openpic_irqs; |
315 | - m48t59_t *nvram; | |
316 | 62 | int unin_memory; |
317 | 63 | int linux_boot, i; |
318 | 64 | unsigned long bios_offset, vga_bios_offset; |
319 | 65 | uint32_t kernel_base, kernel_size, initrd_base, initrd_size; |
320 | 66 | ppc_def_t *def; |
321 | 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 | 74 | int vga_bios_size, bios_size; |
324 | 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 | 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 | 91 | cpu_ppc_reset(env); |
339 | 92 | /* Set time-base frequency to 100 Mhz */ |
340 | 93 | cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); |
94 | +#if 0 | |
341 | 95 | env->osi_call = vga_osi_call; |
96 | +#endif | |
342 | 97 | qemu_register_reset(&cpu_ppc_reset, env); |
343 | 98 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
344 | 99 | envs[i] = env; |
... | ... | @@ -413,143 +168,91 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, |
413 | 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 | 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 | 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 | 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 | 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 | 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 | 257 | if (usb_enabled) { |
555 | 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 | 260 | |
558 | 261 | if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) |
559 | 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 | 278 | kernel_base, kernel_size, |
563 | 279 | kernel_cmdline, |
564 | 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 | 285 | |
570 | 286 | /* Special port to get debug messages from Open-Firmware */ |
571 | 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 | 290 | QEMUMachine core99_machine = { |
603 | 291 | "mac99", |
604 | 292 | "Mac99 based PowerMAC", |
605 | 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 | 527 | { |
528 | 528 | CPUState *env, *envs[MAX_CPUS]; |
529 | 529 | char buf[1024]; |
530 | - m48t59_t *nvram; | |
530 | + nvram_t nvram; | |
531 | + m48t59_t *m48t59; | |
531 | 532 | int PPC_io_memory; |
532 | 533 | int linux_boot, i, nb_nics1, bios_size; |
533 | 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 | 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 | 684 | return; |
684 | - sysctrl->nvram = nvram; | |
685 | + sysctrl->nvram = m48t59; | |
685 | 686 | |
686 | 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 | 692 | kernel_base, kernel_size, |
689 | 693 | kernel_cmdline, |
690 | 694 | initrd_base, initrd_size, | ... | ... |
vl.h
... | ... | @@ -859,12 +859,6 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, |
859 | 859 | /* prep_pci.c */ |
860 | 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 | 862 | /* apb_pci.c */ |
869 | 863 | PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base, |
870 | 864 | qemu_irq *pic); |
... | ... | @@ -892,9 +886,6 @@ enum { |
892 | 886 | qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, |
893 | 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 | 889 | /* gt64xxx.c */ |
899 | 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 | 995 | qemu_irq *pic); |
1005 | 996 | void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, |
1006 | 997 | qemu_irq *pic); |
1007 | -int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq); | |
1008 | 998 | |
1009 | 999 | /* cdrom.c */ |
1010 | 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 | 1232 | void ppc40x_core_reset (CPUState *env); |
1243 | 1233 | void ppc40x_chip_reset (CPUState *env); |
1244 | 1234 | void ppc40x_system_reset (CPUState *env); |
1245 | -#endif | |
1246 | 1235 | void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val); |
1247 | 1236 | |
1248 | 1237 | extern CPUWriteMemoryFunc *PPC_io_write[]; |
1249 | 1238 | extern CPUReadMemoryFunc *PPC_io_read[]; |
1250 | 1239 | void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); |
1240 | +#endif | |
1251 | 1241 | |
1252 | 1242 | /* sun4m.c */ |
1253 | 1243 | extern QEMUMachine ss5_machine, ss10_machine; |
... | ... | @@ -1327,20 +1317,28 @@ void cs_init(target_phys_addr_t base, int irq, void *intctl); |
1327 | 1317 | extern QEMUMachine sun4u_machine; |
1328 | 1318 | |
1329 | 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 | 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 | 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 | 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 | 1342 | const unsigned char *arch, |
1345 | 1343 | uint32_t RAM_size, int boot_device, |
1346 | 1344 | uint32_t kernel_image, uint32_t kernel_size, |
... | ... | @@ -1388,10 +1386,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
1388 | 1386 | void adb_kbd_init(ADBBusState *bus); |
1389 | 1387 | void adb_mouse_init(ADBBusState *bus); |
1390 | 1388 | |
1391 | -/* cuda.c */ | |
1392 | - | |
1393 | 1389 | extern ADBBusState adb_bus; |
1394 | -int cuda_init(qemu_irq irq); | |
1395 | 1390 | |
1396 | 1391 | #include "hw/usb.h" |
1397 | 1392 | ... | ... |