Commit 642012017c13f7562fc2e0d1ce92272814e3010c

Authored by bellard
1 parent 2444ca41

PowerPC prep/chrp/pmac support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@865 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -244,8 +244,8 @@ ifeq ($(TARGET_ARCH), ppc) @@ -244,8 +244,8 @@ ifeq ($(TARGET_ARCH), ppc)
244 VL_OBJS+= ppc.o 244 VL_OBJS+= ppc.o
245 # PREP hardware support 245 # PREP hardware support
246 VL_OBJS+= ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o 246 VL_OBJS+= ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o
247 -VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o ppc_prep.o  
248 -#VL_OBJS+= hw.o of.o setup.o 247 +VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
  248 +VL_OBJS+= ppc_prep.o ppc_chrp.o
249 endif 249 endif
250 ifdef CONFIG_GDBSTUB 250 ifdef CONFIG_GDBSTUB
251 VL_OBJS+=gdbstub.o 251 VL_OBJS+=gdbstub.o
hw/ppc.c
@@ -23,11 +23,6 @@ @@ -23,11 +23,6 @@
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 25
26 -void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,  
27 - DisplayState *ds, const char **fd_filename, int snapshot,  
28 - const char *kernel_filename, const char *kernel_cmdline,  
29 - const char *initrd_filename);  
30 -  
31 /*****************************************************************************/ 26 /*****************************************************************************/
32 /* PPC time base and decrementer emulation */ 27 /* PPC time base and decrementer emulation */
33 //#define DEBUG_TB 28 //#define DEBUG_TB
@@ -202,14 +197,249 @@ void cpu_ppc_reset (CPUState *env) @@ -202,14 +197,249 @@ void cpu_ppc_reset (CPUState *env)
202 } 197 }
203 #endif 198 #endif
204 199
  200 +static void PPC_io_writeb (target_phys_addr_t addr, uint32_t value)
  201 +{
  202 + cpu_outb(NULL, addr & 0xffff, value);
  203 +}
  204 +
  205 +static uint32_t PPC_io_readb (target_phys_addr_t addr)
  206 +{
  207 + uint32_t ret = cpu_inb(NULL, addr & 0xffff);
  208 + return ret;
  209 +}
  210 +
  211 +static void PPC_io_writew (target_phys_addr_t addr, uint32_t value)
  212 +{
  213 +#ifdef TARGET_WORDS_BIGENDIAN
  214 + value = bswap16(value);
  215 +#endif
  216 + cpu_outw(NULL, addr & 0xffff, value);
  217 +}
  218 +
  219 +static uint32_t PPC_io_readw (target_phys_addr_t addr)
  220 +{
  221 + uint32_t ret = cpu_inw(NULL, addr & 0xffff);
  222 +#ifdef TARGET_WORDS_BIGENDIAN
  223 + ret = bswap16(ret);
  224 +#endif
  225 + return ret;
  226 +}
  227 +
  228 +static void PPC_io_writel (target_phys_addr_t addr, uint32_t value)
  229 +{
  230 +#ifdef TARGET_WORDS_BIGENDIAN
  231 + value = bswap32(value);
  232 +#endif
  233 + cpu_outl(NULL, addr & 0xffff, value);
  234 +}
  235 +
  236 +static uint32_t PPC_io_readl (target_phys_addr_t addr)
  237 +{
  238 + uint32_t ret = cpu_inl(NULL, addr & 0xffff);
  239 +
  240 +#ifdef TARGET_WORDS_BIGENDIAN
  241 + ret = bswap32(ret);
  242 +#endif
  243 + return ret;
  244 +}
  245 +
  246 +CPUWriteMemoryFunc *PPC_io_write[] = {
  247 + &PPC_io_writeb,
  248 + &PPC_io_writew,
  249 + &PPC_io_writel,
  250 +};
  251 +
  252 +CPUReadMemoryFunc *PPC_io_read[] = {
  253 + &PPC_io_readb,
  254 + &PPC_io_readw,
  255 + &PPC_io_readl,
  256 +};
  257 +
  258 +/*****************************************************************************/
  259 +/* Debug port */
  260 +void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val)
  261 +{
  262 + addr &= 0xF;
  263 + switch (addr) {
  264 + case 0:
  265 + printf("%c", val);
  266 + break;
  267 + case 1:
  268 + printf("\n");
  269 + fflush(stdout);
  270 + break;
  271 + case 2:
  272 + printf("Set loglevel to %04x\n", val);
  273 + cpu_set_log(val);
  274 + break;
  275 + }
  276 +}
  277 +
  278 +/*****************************************************************************/
  279 +/* NVRAM helpers */
  280 +void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
  281 +{
  282 + m48t59_set_addr(nvram, addr);
  283 + m48t59_write(nvram, value);
  284 +}
  285 +
  286 +uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
  287 +{
  288 + m48t59_set_addr(nvram, addr);
  289 + return m48t59_read(nvram);
  290 +}
  291 +
  292 +void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
  293 +{
  294 + m48t59_set_addr(nvram, addr);
  295 + m48t59_write(nvram, value >> 8);
  296 + m48t59_set_addr(nvram, addr + 1);
  297 + m48t59_write(nvram, value & 0xFF);
  298 +}
  299 +
  300 +uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
  301 +{
  302 + uint16_t tmp;
  303 +
  304 + m48t59_set_addr(nvram, addr);
  305 + tmp = m48t59_read(nvram) << 8;
  306 + m48t59_set_addr(nvram, addr + 1);
  307 + tmp |= m48t59_read(nvram);
  308 +
  309 + return tmp;
  310 +}
  311 +
  312 +void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
  313 +{
  314 + m48t59_set_addr(nvram, addr);
  315 + m48t59_write(nvram, value >> 24);
  316 + m48t59_set_addr(nvram, addr + 1);
  317 + m48t59_write(nvram, (value >> 16) & 0xFF);
  318 + m48t59_set_addr(nvram, addr + 2);
  319 + m48t59_write(nvram, (value >> 8) & 0xFF);
  320 + m48t59_set_addr(nvram, addr + 3);
  321 + m48t59_write(nvram, value & 0xFF);
  322 +}
  323 +
  324 +uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
  325 +{
  326 + uint32_t tmp;
  327 +
  328 + m48t59_set_addr(nvram, addr);
  329 + tmp = m48t59_read(nvram) << 24;
  330 + m48t59_set_addr(nvram, addr + 1);
  331 + tmp |= m48t59_read(nvram) << 16;
  332 + m48t59_set_addr(nvram, addr + 2);
  333 + tmp |= m48t59_read(nvram) << 8;
  334 + m48t59_set_addr(nvram, addr + 3);
  335 + tmp |= m48t59_read(nvram);
  336 +
  337 + return tmp;
  338 +}
  339 +
  340 +void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
  341 + const unsigned char *str, uint32_t max)
  342 +{
  343 + int i;
  344 +
  345 + for (i = 0; i < max && str[i] != '\0'; i++) {
  346 + m48t59_set_addr(nvram, addr + i);
  347 + m48t59_write(nvram, str[i]);
  348 + }
  349 + m48t59_set_addr(nvram, addr + max - 1);
  350 + m48t59_write(nvram, '\0');
  351 +}
  352 +
  353 +int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
  354 +{
  355 + int i;
  356 +
  357 + memset(dst, 0, max);
  358 + for (i = 0; i < max; i++) {
  359 + dst[i] = NVRAM_get_byte(nvram, addr + i);
  360 + if (dst[i] == '\0')
  361 + break;
  362 + }
  363 +
  364 + return i;
  365 +}
  366 +
  367 +static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
  368 +{
  369 + uint16_t tmp;
  370 + uint16_t pd, pd1, pd2;
  371 +
  372 + tmp = prev >> 8;
  373 + pd = prev ^ value;
  374 + pd1 = pd & 0x000F;
  375 + pd2 = ((pd >> 4) & 0x000F) ^ pd1;
  376 + tmp ^= (pd1 << 3) | (pd1 << 8);
  377 + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
  378 +
  379 + return tmp;
  380 +}
  381 +
  382 +uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
  383 +{
  384 + uint32_t i;
  385 + uint16_t crc = 0xFFFF;
  386 + int odd;
  387 +
  388 + odd = count & 1;
  389 + count &= ~1;
  390 + for (i = 0; i != count; i++) {
  391 + crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
  392 + }
  393 + if (odd) {
  394 + crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
  395 + }
  396 +
  397 + return crc;
  398 +}
  399 +
  400 +int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
  401 + const unsigned char *arch,
  402 + uint32_t RAM_size, int boot_device,
  403 + uint32_t kernel_image, uint32_t kernel_size,
  404 + uint32_t cmdline, uint32_t cmdline_size,
  405 + uint32_t initrd_image, uint32_t initrd_size,
  406 + uint32_t NVRAM_image)
  407 +{
  408 + uint16_t crc;
  409 +
  410 + /* Set parameters for Open Hack'Ware BIOS */
  411 + NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
  412 + NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
  413 + NVRAM_set_word(nvram, 0x14, NVRAM_size);
  414 + NVRAM_set_string(nvram, 0x20, arch, 16);
  415 + NVRAM_set_lword(nvram, 0x30, RAM_size);
  416 + NVRAM_set_byte(nvram, 0x34, boot_device);
  417 + NVRAM_set_lword(nvram, 0x38, kernel_image);
  418 + NVRAM_set_lword(nvram, 0x3C, kernel_size);
  419 + NVRAM_set_lword(nvram, 0x40, cmdline);
  420 + NVRAM_set_lword(nvram, 0x44, cmdline_size);
  421 + NVRAM_set_lword(nvram, 0x48, initrd_image);
  422 + NVRAM_set_lword(nvram, 0x4C, initrd_size);
  423 + NVRAM_set_lword(nvram, 0x50, NVRAM_image);
  424 + crc = NVRAM_compute_crc(nvram, 0x00, 0x5C);
  425 + NVRAM_set_word(nvram, 0x5C, crc);
  426 +
  427 + return 0;
  428 + }
  429 +
205 /*****************************************************************************/ 430 /*****************************************************************************/
206 void ppc_init (int ram_size, int vga_ram_size, int boot_device, 431 void ppc_init (int ram_size, int vga_ram_size, int boot_device,
207 DisplayState *ds, const char **fd_filename, int snapshot, 432 DisplayState *ds, const char **fd_filename, int snapshot,
208 const char *kernel_filename, const char *kernel_cmdline, 433 const char *kernel_filename, const char *kernel_cmdline,
209 const char *initrd_filename) 434 const char *initrd_filename)
210 { 435 {
211 - /* For now, only PREP is supported */  
212 - return ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,  
213 - snapshot, kernel_filename, kernel_cmdline,  
214 - initrd_filename); 436 + if (prep_enabled) {
  437 + ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
  438 + snapshot, kernel_filename, kernel_cmdline,
  439 + initrd_filename);
  440 + } else {
  441 + ppc_chrp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
  442 + snapshot, kernel_filename, kernel_cmdline,
  443 + initrd_filename);
  444 + }
215 } 445 }
hw/ppc_chrp.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU PPC CHRP/PMAC hardware System Emulator
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * 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 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +
  26 +#define BIOS_FILENAME "ppc_rom.bin"
  27 +#define NVRAM_SIZE 0x2000
  28 +
  29 +/* PowerPC PREP hardware initialisation */
  30 +void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
  31 + DisplayState *ds, const char **fd_filename, int snapshot,
  32 + const char *kernel_filename, const char *kernel_cmdline,
  33 + const char *initrd_filename)
  34 +{
  35 + char buf[1024];
  36 + m48t59_t *nvram;
  37 + int PPC_io_memory;
  38 + int ret, linux_boot, i, fd;
  39 + unsigned long bios_offset;
  40 +
  41 + linux_boot = (kernel_filename != NULL);
  42 +
  43 + /* allocate RAM */
  44 + cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
  45 +
  46 + /* allocate and load BIOS */
  47 + bios_offset = ram_size + vga_ram_size;
  48 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  49 + ret = load_image(buf, phys_ram_base + bios_offset);
  50 + if (ret != BIOS_SIZE) {
  51 + fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
  52 + exit(1);
  53 + }
  54 + cpu_register_physical_memory((uint32_t)(-BIOS_SIZE),
  55 + BIOS_SIZE, bios_offset | IO_MEM_ROM);
  56 + cpu_single_env->nip = 0xfffffffc;
  57 +
  58 + /* Register CPU as a 74x/75x */
  59 + cpu_ppc_register(cpu_single_env, 0x00080000);
  60 + /* Set time-base frequency to 100 Mhz */
  61 + cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
  62 +
  63 + isa_mem_base = 0xc0000000;
  64 + pci_pmac_init();
  65 +
  66 + /* Register 64 KB of ISA IO space */
  67 + PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
  68 + cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);
  69 + // cpu_register_physical_memory(0xfe000000, 0xfe010000, PPC_io_memory);
  70 +
  71 + /* init basic PC hardware */
  72 + vga_initialize(ds, phys_ram_base + ram_size, ram_size,
  73 + vga_ram_size, 1);
  74 + // openpic = openpic_init(0x00000000, 0xF0000000, 1);
  75 + // pic_init(openpic);
  76 + pic_init();
  77 + // pit = pit_init(0x40, 0);
  78 +
  79 + /* XXX: use Mac Serial port */
  80 + fd = serial_open_device();
  81 + serial_init(0x3f8, 4, fd);
  82 +
  83 + for(i = 0; i < nb_nics; i++) {
  84 + pci_ne2000_init(&nd_table[i]);
  85 + }
  86 +
  87 + pci_ide_init(bs_table);
  88 +
  89 + kbd_init();
  90 +
  91 + nvram = m48t59_init(8, 0x0074, NVRAM_SIZE);
  92 +
  93 + PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
  94 + 0, 0,
  95 + 0,
  96 + 0,
  97 + 0, 0,
  98 + /* XXX: need an option to load a NVRAM image */
  99 + 0
  100 + );
  101 +
  102 + /* Special port to get debug messages from Open-Firmware */
  103 + register_ioport_write(0xFF00, 0x04, 1, &PREP_debug_write, NULL);
  104 + register_ioport_write(0xFF00, 0x04, 2, &PREP_debug_write, NULL);
  105 +
  106 + pci_ppc_bios_init();
  107 +}
hw/ppc_prep.c
@@ -22,14 +22,13 @@ @@ -22,14 +22,13 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 -#include "m48t59.h"  
26 -  
27 -/* XXX: move all TB related stuff in ppc_prep.c and suppress ppc.c ? */  
28 -ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);  
29 25
30 //#define HARD_DEBUG_PPC_IO 26 //#define HARD_DEBUG_PPC_IO
31 //#define DEBUG_PPC_IO 27 //#define DEBUG_PPC_IO
32 28
  29 +#define KERNEL_LOAD_ADDR 0x01000000;
  30 +#define INITRD_LOAD_ADDR 0x01800000;
  31 +
33 extern int loglevel; 32 extern int loglevel;
34 extern FILE *logfile; 33 extern FILE *logfile;
35 34
@@ -58,42 +57,7 @@ do { \ @@ -58,42 +57,7 @@ do { \
58 #endif 57 #endif
59 58
60 #define BIOS_FILENAME "ppc_rom.bin" 59 #define BIOS_FILENAME "ppc_rom.bin"
61 -  
62 -#define KERNEL_LOAD_ADDR 0x00000000  
63 -#define KERNEL_STACK_ADDR 0x00400000  
64 -#define INITRD_LOAD_ADDR 0x00800000  
65 -  
66 -int load_kernel(const char *filename, uint8_t *addr,  
67 - uint8_t *real_addr)  
68 -{  
69 - int fd, size;  
70 - int setup_sects;  
71 -  
72 - fd = open(filename, O_RDONLY);  
73 - if (fd < 0)  
74 - return -1;  
75 -  
76 - /* load 16 bit code */  
77 - if (read(fd, real_addr, 512) != 512)  
78 - goto fail;  
79 - setup_sects = real_addr[0x1F1];  
80 - if (!setup_sects)  
81 - setup_sects = 4;  
82 - if (read(fd, real_addr + 512, setup_sects * 512) !=  
83 - setup_sects * 512)  
84 - goto fail;  
85 -  
86 - /* load 32 bit code */  
87 - size = read(fd, addr, 16 * 1024 * 1024);  
88 - if (size < 0)  
89 - goto fail;  
90 - close(fd);  
91 - return size;  
92 - fail:  
93 - close(fd);  
94 - return -1;  
95 -}  
96 - 60 +/* Constants for devices init */
97 static const int ide_iobase[2] = { 0x1f0, 0x170 }; 61 static const int ide_iobase[2] = { 0x1f0, 0x170 };
98 static const int ide_iobase2[2] = { 0x3f6, 0x376 }; 62 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
99 static const int ide_irq[2] = { 13, 13 }; 63 static const int ide_irq[2] = { 13, 13 };
@@ -103,218 +67,300 @@ static const int ide_irq[2] = { 13, 13 }; @@ -103,218 +67,300 @@ static const int ide_irq[2] = { 13, 13 };
103 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; 67 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
104 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; 68 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
105 69
106 -/* IO ports emulation */ 70 +//static PITState *pit;
  71 +
  72 +/* ISA IO ports bridge */
107 #define PPC_IO_BASE 0x80000000 73 #define PPC_IO_BASE 0x80000000
108 74
109 -static void PPC_io_writeb (target_phys_addr_t addr, uint32_t value) 75 +/* Speaker port 0x61 */
  76 +int speaker_data_on;
  77 +int dummy_refresh_clock;
  78 +
  79 +static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
110 { 80 {
111 - /* Don't polute serial port output */  
112 #if 0 81 #if 0
113 - if ((addr < 0x800003F0 || addr > 0x80000400) &&  
114 - (addr < 0x80000074 || addr > 0x80000077) &&  
115 - (addr < 0x80000020 || addr > 0x80000021) &&  
116 - (addr < 0x800000a0 || addr > 0x800000a1) &&  
117 - (addr < 0x800001f0 || addr > 0x800001f7) &&  
118 - (addr < 0x80000170 || addr > 0x80000177)) 82 + speaker_data_on = (val >> 1) & 1;
  83 + pit_set_gate(pit, 2, val & 1);
119 #endif 84 #endif
120 - {  
121 - PPC_IO_DPRINTF("0x%08x => 0x%02x\n", addr - PPC_IO_BASE, value);  
122 - }  
123 - cpu_outb(NULL, addr - PPC_IO_BASE, value);  
124 } 85 }
125 86
126 -static uint32_t PPC_io_readb (target_phys_addr_t addr) 87 +static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
127 { 88 {
128 - uint32_t ret = cpu_inb(NULL, addr - PPC_IO_BASE);  
129 -  
130 #if 0 89 #if 0
131 - if ((addr < 0x800003F0 || addr > 0x80000400) &&  
132 - (addr < 0x80000074 || addr > 0x80000077) &&  
133 - (addr < 0x80000020 || addr > 0x80000021) &&  
134 - (addr < 0x800000a0 || addr > 0x800000a1) &&  
135 - (addr < 0x800001f0 || addr > 0x800001f7) &&  
136 - (addr < 0x80000170 || addr > 0x80000177) &&  
137 - (addr < 0x8000060 || addr > 0x8000064)) 90 + int out;
  91 + out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
  92 + dummy_refresh_clock ^= 1;
  93 + return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
  94 + (dummy_refresh_clock << 4);
138 #endif 95 #endif
139 - {  
140 - PPC_IO_DPRINTF("0x%08x <= 0x%02x\n", addr - PPC_IO_BASE, ret);  
141 - }  
142 - return ret; 96 + return 0;
143 } 97 }
144 98
145 -static void PPC_io_writew (target_phys_addr_t addr, uint32_t value) 99 +/* PCI intack register */
  100 +/* Read-only register (?) */
  101 +static void _PPC_intack_write (target_phys_addr_t addr, uint32_t value)
  102 +{
  103 + // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
  104 +}
  105 +
  106 +static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
  107 +{
  108 + uint32_t retval = 0;
  109 +
  110 + if (addr == 0xBFFFFFF0)
  111 + retval = pic_intack_read(NULL);
  112 + // printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
  113 +
  114 + return retval;
  115 +}
  116 +
  117 +static uint32_t PPC_intack_readb (target_phys_addr_t addr)
  118 +{
  119 + return _PPC_intack_read(addr);
  120 +}
  121 +
  122 +static uint32_t PPC_intack_readw (target_phys_addr_t addr)
146 { 123 {
147 - if ((addr < 0x800001f0 || addr > 0x800001f7) &&  
148 - (addr < 0x80000170 || addr > 0x80000177)) {  
149 - PPC_IO_DPRINTF("0x%08x => 0x%04x\n", addr - PPC_IO_BASE, value);  
150 - }  
151 #ifdef TARGET_WORDS_BIGENDIAN 124 #ifdef TARGET_WORDS_BIGENDIAN
152 - value = bswap16(value); 125 + return bswap16(_PPC_intack_read(addr));
  126 +#else
  127 + return _PPC_intack_read(addr);
153 #endif 128 #endif
154 - cpu_outw(NULL, addr - PPC_IO_BASE, value);  
155 } 129 }
156 130
157 -static uint32_t PPC_io_readw (target_phys_addr_t addr) 131 +static uint32_t PPC_intack_readl (target_phys_addr_t addr)
158 { 132 {
159 - uint32_t ret = cpu_inw(NULL, addr - PPC_IO_BASE);  
160 #ifdef TARGET_WORDS_BIGENDIAN 133 #ifdef TARGET_WORDS_BIGENDIAN
161 - ret = bswap16(ret); 134 + return bswap32(_PPC_intack_read(addr));
  135 +#else
  136 + return _PPC_intack_read(addr);
162 #endif 137 #endif
163 - if ((addr < 0x800001f0 || addr > 0x800001f7) &&  
164 - (addr < 0x80000170 || addr > 0x80000177)) {  
165 - PPC_IO_DPRINTF("0x%08x <= 0x%04x\n", addr - PPC_IO_BASE, ret);  
166 - }  
167 - return ret;  
168 } 138 }
169 139
170 -static void PPC_io_writel (target_phys_addr_t addr, uint32_t value) 140 +static CPUWriteMemoryFunc *PPC_intack_write[] = {
  141 + &_PPC_intack_write,
  142 + &_PPC_intack_write,
  143 + &_PPC_intack_write,
  144 +};
  145 +
  146 +static CPUReadMemoryFunc *PPC_intack_read[] = {
  147 + &PPC_intack_readb,
  148 + &PPC_intack_readw,
  149 + &PPC_intack_readl,
  150 +};
  151 +
  152 +/* PowerPC control and status registers */
  153 +#if 0 // Not used
  154 +static struct {
  155 + /* IDs */
  156 + uint32_t veni_devi;
  157 + uint32_t revi;
  158 + /* Control and status */
  159 + uint32_t gcsr;
  160 + uint32_t xcfr;
  161 + uint32_t ct32;
  162 + uint32_t mcsr;
  163 + /* General purpose registers */
  164 + uint32_t gprg[6];
  165 + /* Exceptions */
  166 + uint32_t feen;
  167 + uint32_t fest;
  168 + uint32_t fema;
  169 + uint32_t fecl;
  170 + uint32_t eeen;
  171 + uint32_t eest;
  172 + uint32_t eecl;
  173 + uint32_t eeint;
  174 + uint32_t eemck0;
  175 + uint32_t eemck1;
  176 + /* Error diagnostic */
  177 +} XCSR;
  178 +#endif
  179 +
  180 +static void PPC_XCSR_writeb (target_phys_addr_t addr, uint32_t value)
  181 +{
  182 + printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
  183 +}
  184 +
  185 +static void PPC_XCSR_writew (target_phys_addr_t addr, uint32_t value)
171 { 186 {
172 - PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, value);  
173 #ifdef TARGET_WORDS_BIGENDIAN 187 #ifdef TARGET_WORDS_BIGENDIAN
174 - value = bswap32(value); 188 + value = bswap16(value);
175 #endif 189 #endif
176 - cpu_outl(NULL, addr - PPC_IO_BASE, value); 190 + printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
177 } 191 }
178 192
179 -static uint32_t PPC_io_readl (target_phys_addr_t addr) 193 +static void PPC_XCSR_writel (target_phys_addr_t addr, uint32_t value)
180 { 194 {
181 - uint32_t ret = cpu_inl(NULL, addr - PPC_IO_BASE);  
182 -  
183 #ifdef TARGET_WORDS_BIGENDIAN 195 #ifdef TARGET_WORDS_BIGENDIAN
184 - ret = bswap32(ret); 196 + value = bswap32(value);
185 #endif 197 #endif
186 - PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, ret);  
187 - return ret; 198 + printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
188 } 199 }
189 200
190 -static CPUWriteMemoryFunc *PPC_io_write[] = {  
191 - &PPC_io_writeb,  
192 - &PPC_io_writew,  
193 - &PPC_io_writel,  
194 -}; 201 +static uint32_t PPC_XCSR_readb (target_phys_addr_t addr)
  202 +{
  203 + uint32_t retval = 0;
195 204
196 -static CPUReadMemoryFunc *PPC_io_read[] = {  
197 - &PPC_io_readb,  
198 - &PPC_io_readw,  
199 - &PPC_io_readl,  
200 -}; 205 + printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
201 206
202 -/* Read-only register (?) */  
203 -static void _PPC_ioB_write (target_phys_addr_t addr, uint32_t value) 207 + return retval;
  208 +}
  209 +
  210 +static uint32_t PPC_XCSR_readw (target_phys_addr_t addr)
204 { 211 {
205 - // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value); 212 + uint32_t retval = 0;
  213 +
  214 + printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
  215 +#ifdef TARGET_WORDS_BIGENDIAN
  216 + retval = bswap16(retval);
  217 +#endif
  218 +
  219 + return retval;
206 } 220 }
207 221
208 -static uint32_t _PPC_ioB_read (target_phys_addr_t addr) 222 +static uint32_t PPC_XCSR_readl (target_phys_addr_t addr)
209 { 223 {
210 uint32_t retval = 0; 224 uint32_t retval = 0;
211 225
212 - if (addr == 0xBFFFFFF0)  
213 - retval = pic_intack_read(NULL);  
214 - // printf("%s: 0x%08x <= %d\n", __func__, addr, retval); 226 + printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
  227 +#ifdef TARGET_WORDS_BIGENDIAN
  228 + retval = bswap32(retval);
  229 +#endif
215 230
216 return retval; 231 return retval;
217 } 232 }
218 233
219 -static CPUWriteMemoryFunc *PPC_ioB_write[] = {  
220 - &_PPC_ioB_write,  
221 - &_PPC_ioB_write,  
222 - &_PPC_ioB_write, 234 +static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
  235 + &PPC_XCSR_writeb,
  236 + &PPC_XCSR_writew,
  237 + &PPC_XCSR_writel,
223 }; 238 };
224 239
225 -static CPUReadMemoryFunc *PPC_ioB_read[] = {  
226 - &_PPC_ioB_read,  
227 - &_PPC_ioB_read,  
228 - &_PPC_ioB_read, 240 +static CPUReadMemoryFunc *PPC_XCSR_read[] = {
  241 + &PPC_XCSR_readb,
  242 + &PPC_XCSR_readw,
  243 + &PPC_XCSR_readl,
229 }; 244 };
230 245
231 -#if 0  
232 -static CPUWriteMemoryFunc *PPC_io3_write[] = {  
233 - &PPC_io3_writeb,  
234 - &PPC_io3_writew,  
235 - &PPC_io3_writel,  
236 -}; 246 +/* Fake super-io ports for PREP platform (Intel 82378ZB) */
  247 +typedef struct sysctrl_t {
  248 + m48t59_t *nvram;
  249 + uint8_t state;
  250 + uint8_t syscontrol;
  251 + uint8_t fake_io[2];
  252 +} sysctrl_t;
237 253
238 -static CPUReadMemoryFunc *PPC_io3_read[] = {  
239 - &PPC_io3_readb,  
240 - &PPC_io3_readw,  
241 - &PPC_io3_readl, 254 +enum {
  255 + STATE_HARDFILE = 0x01,
242 }; 256 };
243 -#endif  
244 257
245 -/* Fake super-io ports for PREP platform (Intel 82378ZB) */  
246 -static uint8_t PREP_fake_io[2];  
247 -static uint8_t NVRAM_lock; 258 +static sysctrl_t *sysctrl;
248 259
249 static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val) 260 static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
250 { 261 {
251 - PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val);  
252 - PREP_fake_io[addr - 0x0398] = val; 262 + sysctrl_t *sysctrl = opaque;
  263 +
  264 + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
  265 + sysctrl->fake_io[addr - 0x0398] = val;
253 } 266 }
254 267
255 static uint32_t PREP_io_read (void *opaque, uint32_t addr) 268 static uint32_t PREP_io_read (void *opaque, uint32_t addr)
256 { 269 {
257 - PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, PREP_fake_io[addr - 0x0398]);  
258 - return PREP_fake_io[addr - 0x0398];  
259 -} 270 + sysctrl_t *sysctrl = opaque;
260 271
261 -static uint8_t syscontrol; 272 + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
  273 + sysctrl->fake_io[addr - 0x0398]);
  274 + return sysctrl->fake_io[addr - 0x0398];
  275 +}
262 276
263 static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) 277 static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
264 { 278 {
265 - PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val); 279 + sysctrl_t *sysctrl = opaque;
  280 +
  281 + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
266 switch (addr) { 282 switch (addr) {
267 case 0x0092: 283 case 0x0092:
268 /* Special port 92 */ 284 /* Special port 92 */
269 /* Check soft reset asked */ 285 /* Check soft reset asked */
270 - if (val & 0x80) {  
271 - printf("Soft reset asked... Stop emulation\n");  
272 - abort(); 286 + if (val & 0x01) {
  287 + // cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
273 } 288 }
274 /* Check LE mode */ 289 /* Check LE mode */
275 - if (val & 0x40) { 290 + if (val & 0x02) {
276 printf("Little Endian mode isn't supported (yet ?)\n"); 291 printf("Little Endian mode isn't supported (yet ?)\n");
277 abort(); 292 abort();
278 } 293 }
279 break; 294 break;
  295 + case 0x0800:
  296 + /* Motorola CPU configuration register : read-only */
  297 + break;
  298 + case 0x0802:
  299 + /* Motorola base module feature register : read-only */
  300 + break;
  301 + case 0x0803:
  302 + /* Motorola base module status register : read-only */
  303 + break;
280 case 0x0808: 304 case 0x0808:
281 - /* Hardfile light register: don't care */ 305 + /* Hardfile light register */
  306 + if (val & 1)
  307 + sysctrl->state |= STATE_HARDFILE;
  308 + else
  309 + sysctrl->state &= ~STATE_HARDFILE;
282 break; 310 break;
283 case 0x0810: 311 case 0x0810:
284 /* Password protect 1 register */ 312 /* Password protect 1 register */
285 - NVRAM_lock ^= 0x01; 313 + if (sysctrl->nvram != NULL)
  314 + m48t59_toggle_lock(sysctrl->nvram, 1);
286 break; 315 break;
287 case 0x0812: 316 case 0x0812:
288 /* Password protect 2 register */ 317 /* Password protect 2 register */
289 - NVRAM_lock ^= 0x02; 318 + if (sysctrl->nvram != NULL)
  319 + m48t59_toggle_lock(sysctrl->nvram, 2);
290 break; 320 break;
291 case 0x0814: 321 case 0x0814:
292 - /* L2 invalidate register: don't care */ 322 + /* L2 invalidate register */
  323 + // tlb_flush(cpu_single_env, 1);
293 break; 324 break;
294 case 0x081C: 325 case 0x081C:
295 /* system control register */ 326 /* system control register */
296 - syscontrol = val; 327 + sysctrl->syscontrol = val & 0x0F;
297 break; 328 break;
298 case 0x0850: 329 case 0x0850:
299 /* I/O map type register */ 330 /* I/O map type register */
300 - if (val & 0x80) { 331 + if (!(val & 0x01)) {
301 printf("No support for non-continuous I/O map mode\n"); 332 printf("No support for non-continuous I/O map mode\n");
302 abort(); 333 abort();
303 } 334 }
304 break; 335 break;
305 default: 336 default:
  337 + printf("ERROR: unaffected IO port write: %04lx => %02x\n",
  338 + (long)addr, val);
306 break; 339 break;
307 } 340 }
308 } 341 }
309 342
310 static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) 343 static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
311 { 344 {
  345 + sysctrl_t *sysctrl = opaque;
312 uint32_t retval = 0xFF; 346 uint32_t retval = 0xFF;
313 347
314 switch (addr) { 348 switch (addr) {
315 case 0x0092: 349 case 0x0092:
316 /* Special port 92 */ 350 /* Special port 92 */
317 - retval = 0x40; 351 + retval = 0x00;
  352 + break;
  353 + case 0x0800:
  354 + /* Motorola CPU configuration register */
  355 + retval = 0xEF; /* MPC750 */
  356 + break;
  357 + case 0x0802:
  358 + /* Motorola Base module feature register */
  359 + retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
  360 + break;
  361 + case 0x0803:
  362 + /* Motorola base module status register */
  363 + retval = 0xE0; /* Standard MPC750 */
318 break; 364 break;
319 case 0x080C: 365 case 0x080C:
320 /* Equipment present register: 366 /* Equipment present register:
@@ -323,7 +369,11 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) @@ -323,7 +369,11 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
323 * no cards in PCI slots 369 * no cards in PCI slots
324 * SCSI fuse is bad 370 * SCSI fuse is bad
325 */ 371 */
326 - retval = 0xFC; 372 + retval = 0x3C;
  373 + break;
  374 + case 0x0810:
  375 + /* Motorola base module extended feature register */
  376 + retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
327 break; 377 break;
328 case 0x0818: 378 case 0x0818:
329 /* Keylock */ 379 /* Keylock */
@@ -333,7 +383,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) @@ -333,7 +383,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
333 /* system control register 383 /* system control register
334 * 7 - 6 / 1 - 0: L2 cache enable 384 * 7 - 6 / 1 - 0: L2 cache enable
335 */ 385 */
336 - retval = syscontrol; 386 + retval = sysctrl->syscontrol;
337 break; 387 break;
338 case 0x0823: 388 case 0x0823:
339 /* */ 389 /* */
@@ -341,561 +391,20 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) @@ -341,561 +391,20 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
341 break; 391 break;
342 case 0x0850: 392 case 0x0850:
343 /* I/O map type register */ 393 /* I/O map type register */
344 - retval = 0x00; 394 + retval = 0x01;
345 break; 395 break;
346 default: 396 default:
  397 + printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
347 break; 398 break;
348 } 399 }
349 - PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, retval); 400 + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
350 401
351 return retval; 402 return retval;
352 } 403 }
353 404
354 -#define NVRAM_SIZE 0x2000  
355 -#define NVRAM_END 0x1FF0  
356 -#define NVRAM_OSAREA_SIZE 512  
357 -#define NVRAM_CONFSIZE 1024  
358 -  
359 -static inline void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)  
360 -{  
361 - m48t59_set_addr(nvram, addr);  
362 - m48t59_write(nvram, value);  
363 -}  
364 -  
365 -static inline uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)  
366 -{  
367 - m48t59_set_addr(nvram, addr);  
368 - return m48t59_read(nvram);  
369 -}  
370 -  
371 -static inline void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)  
372 -{  
373 - m48t59_set_addr(nvram, addr);  
374 - m48t59_write(nvram, value >> 8);  
375 - m48t59_set_addr(nvram, addr + 1);  
376 - m48t59_write(nvram, value & 0xFF);  
377 -}  
378 -  
379 -static inline uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)  
380 -{  
381 - uint16_t tmp;  
382 -  
383 - m48t59_set_addr(nvram, addr);  
384 - tmp = m48t59_read(nvram) << 8;  
385 - m48t59_set_addr(nvram, addr + 1);  
386 - tmp |= m48t59_read(nvram);  
387 -  
388 - return tmp;  
389 -}  
390 -  
391 -static inline void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr,  
392 - uint32_t value)  
393 -{  
394 - m48t59_set_addr(nvram, addr);  
395 - m48t59_write(nvram, value >> 24);  
396 - m48t59_set_addr(nvram, addr + 1);  
397 - m48t59_write(nvram, (value >> 16) & 0xFF);  
398 - m48t59_set_addr(nvram, addr + 2);  
399 - m48t59_write(nvram, (value >> 8) & 0xFF);  
400 - m48t59_set_addr(nvram, addr + 3);  
401 - m48t59_write(nvram, value & 0xFF);  
402 -}  
403 -  
404 -static inline uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)  
405 -{  
406 - uint32_t tmp;  
407 -  
408 - m48t59_set_addr(nvram, addr);  
409 - tmp = m48t59_read(nvram) << 24;  
410 - m48t59_set_addr(nvram, addr + 1);  
411 - tmp |= m48t59_read(nvram) << 16;  
412 - m48t59_set_addr(nvram, addr + 2);  
413 - tmp |= m48t59_read(nvram) << 8;  
414 - m48t59_set_addr(nvram, addr + 3);  
415 - tmp |= m48t59_read(nvram);  
416 -  
417 - return tmp;  
418 -}  
419 -  
420 -static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)  
421 -{  
422 - uint16_t tmp;  
423 - uint16_t pd, pd1, pd2;  
424 -  
425 - tmp = prev >> 8;  
426 - pd = prev ^ value;  
427 - pd1 = pd & 0x000F;  
428 - pd2 = ((pd >> 4) & 0x000F) ^ pd1;  
429 - tmp ^= (pd1 << 3) | (pd1 << 8);  
430 - tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);  
431 -  
432 - return tmp;  
433 -}  
434 -  
435 -static void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,  
436 - uint32_t start, uint32_t count)  
437 -{  
438 - uint32_t i;  
439 - uint16_t crc = 0xFFFF;  
440 - int odd = 0;  
441 -  
442 - if (count & 1)  
443 - odd = 1;  
444 - count &= ~1;  
445 - for (i = 0; i != count; i++) {  
446 - crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));  
447 - }  
448 - if (odd) {  
449 - crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);  
450 - }  
451 - NVRAM_set_word(nvram, addr, crc);  
452 -}  
453 -  
454 -static void prep_NVRAM_init (void)  
455 -{  
456 - m48t59_t *nvram;  
457 -  
458 - nvram = m48t59_init(8, 0x0074, NVRAM_SIZE);  
459 - /* NVRAM header */  
460 - /* 0x00: NVRAM size in kB */  
461 - NVRAM_set_word(nvram, 0x00, NVRAM_SIZE >> 10);  
462 - /* 0x02: NVRAM version */  
463 - NVRAM_set_byte(nvram, 0x02, 0x01);  
464 - /* 0x03: NVRAM revision */  
465 - NVRAM_set_byte(nvram, 0x03, 0x01);  
466 - /* 0x08: last OS */  
467 - NVRAM_set_byte(nvram, 0x08, 0x00); /* Unknown */  
468 - /* 0x09: endian */  
469 - NVRAM_set_byte(nvram, 0x09, 'B'); /* Big-endian */  
470 - /* 0x0A: OSArea usage */  
471 - NVRAM_set_byte(nvram, 0x0A, 0x00); /* Empty */  
472 - /* 0x0B: PM mode */  
473 - NVRAM_set_byte(nvram, 0x0B, 0x00); /* Normal */  
474 - /* Restart block description record */  
475 - /* 0x0C: restart block version */  
476 - NVRAM_set_word(nvram, 0x0C, 0x01);  
477 - /* 0x0E: restart block revision */  
478 - NVRAM_set_word(nvram, 0x0E, 0x01);  
479 - /* 0x20: restart address */  
480 - NVRAM_set_lword(nvram, 0x20, 0x00);  
481 - /* 0x24: save area address */  
482 - NVRAM_set_lword(nvram, 0x24, 0x00);  
483 - /* 0x28: save area length */  
484 - NVRAM_set_lword(nvram, 0x28, 0x00);  
485 - /* 0x1C: checksum of restart block */  
486 - NVRAM_set_crc(nvram, 0x1C, 0x0C, 32);  
487 -  
488 - /* Security section */  
489 - /* Set all to zero */  
490 - /* 0xC4: pointer to global environment area */  
491 - NVRAM_set_lword(nvram, 0xC4, 0x0100);  
492 - /* 0xC8: size of global environment area */  
493 - NVRAM_set_lword(nvram, 0xC8,  
494 - NVRAM_END - NVRAM_OSAREA_SIZE - NVRAM_CONFSIZE - 0x0100);  
495 - /* 0xD4: pointer to configuration area */  
496 - NVRAM_set_lword(nvram, 0xD4, NVRAM_END - NVRAM_CONFSIZE);  
497 - /* 0xD8: size of configuration area */  
498 - NVRAM_set_lword(nvram, 0xD8, NVRAM_CONFSIZE);  
499 - /* 0xE8: pointer to OS specific area */  
500 - NVRAM_set_lword(nvram, 0xE8,  
501 - NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);  
502 - /* 0xD8: size of OS specific area */  
503 - NVRAM_set_lword(nvram, 0xEC, NVRAM_OSAREA_SIZE);  
504 -  
505 - /* Configuration area */  
506 - /* RTC init */  
507 - // NVRAM_set_lword(nvram, 0x1FFC, 0x50);  
508 -  
509 - /* 0x04: checksum 0 => OS area */  
510 - NVRAM_set_crc(nvram, 0x04, 0x00,  
511 - NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);  
512 - /* 0x06: checksum of config area */  
513 - NVRAM_set_crc(nvram, 0x06, NVRAM_END - NVRAM_CONFSIZE, NVRAM_CONFSIZE);  
514 -}  
515 -  
516 -int load_initrd (const char *filename, uint8_t *addr)  
517 -{  
518 - int fd, size;  
519 -  
520 - printf("Load initrd\n");  
521 - fd = open(filename, O_RDONLY);  
522 - if (fd < 0)  
523 - return -1;  
524 - size = read(fd, addr, 16 * 1024 * 1024);  
525 - if (size < 0)  
526 - goto fail;  
527 - close(fd);  
528 - printf("Load initrd: %d\n", size);  
529 - return size;  
530 - fail:  
531 - close(fd);  
532 - printf("Load initrd failed\n");  
533 - return -1;  
534 -}  
535 -  
536 -/* Quick hack for PPC memory infos... */  
537 -static void put_long (void *addr, uint32_t l)  
538 -{  
539 - char *pos = addr;  
540 - pos[0] = (l >> 24) & 0xFF;  
541 - pos[1] = (l >> 16) & 0xFF;  
542 - pos[2] = (l >> 8) & 0xFF;  
543 - pos[3] = l & 0xFF;  
544 -}  
545 -  
546 -/* bootloader infos are in the form:  
547 - * uint32_t TAG  
548 - * uint32_t TAG_size (from TAG to next TAG).  
549 - * data  
550 - * ....  
551 - */  
552 -#if !defined (USE_OPEN_FIRMWARE)  
553 -static void *set_bootinfo_tag (void *addr, uint32_t tag, uint32_t size,  
554 - void *data)  
555 -{  
556 - char *pos = addr;  
557 -  
558 - put_long(pos, tag);  
559 - pos += 4;  
560 - put_long(pos, size + 8);  
561 - pos += 4;  
562 - memcpy(pos, data, size);  
563 - pos += size;  
564 -  
565 - return pos;  
566 -}  
567 -#endif  
568 -  
569 -typedef struct boot_dev_t {  
570 - const unsigned char *name;  
571 - int major;  
572 - int minor;  
573 -} boot_dev_t;  
574 -  
575 -static boot_dev_t boot_devs[] =  
576 -{  
577 - { "/dev/fd0", 2, 0, },  
578 - { "/dev/fd1", 2, 1, },  
579 - { "/dev/hda", 3, 1, },  
580 -// { "/dev/ide/host0/bus0/target0/lun0/part1", 3, 1, },  
581 -// { "/dev/hdc", 22, 0, },  
582 - { "/dev/hdc", 22, 1, },  
583 - { "/dev/ram0 init=/linuxrc", 1, 0, },  
584 -};  
585 -  
586 -/* BATU:  
587 - * BEPI : bloc virtual address  
588 - * BL : area size bits (128 kB is 0, 256 1, 512 3, ...  
589 - * Vs/Vp  
590 - * BATL:  
591 - * BPRN : bloc real address align on 4MB boundary  
592 - * WIMG : cache access mode : not used  
593 - * PP : protection bits  
594 - */  
595 -static void setup_BAT (CPUPPCState *env, int BAT,  
596 - uint32_t virtual, uint32_t physical,  
597 - uint32_t size, int Vs, int Vp, int PP)  
598 -{  
599 - uint32_t sz_bits, tmp_sz, align, tmp;  
600 -  
601 - sz_bits = 0;  
602 - align = 131072;  
603 - for (tmp_sz = size / 131072; tmp_sz != 1; tmp_sz = tmp_sz >> 1) {  
604 - sz_bits = (sz_bits << 1) + 1;  
605 - align = align << 1;  
606 - }  
607 - tmp = virtual & ~(align - 1); /* Align virtual area start */  
608 - tmp |= sz_bits << 2; /* Fix BAT size */  
609 - tmp |= Vs << 1; /* Supervisor access */  
610 - tmp |= Vp; /* User access */  
611 - env->DBAT[0][BAT] = tmp;  
612 - env->IBAT[0][BAT] = tmp;  
613 - tmp = physical & ~(align - 1); /* Align physical area start */  
614 - tmp |= 0; /* Don't care about WIMG */  
615 - tmp |= PP; /* Protection */  
616 - env->DBAT[1][BAT] = tmp;  
617 - env->IBAT[1][BAT] = tmp;  
618 - printf("Set BATU0 to 0x%08x BATL0 to 0x%08x\n",  
619 - env->DBAT[0][BAT], env->DBAT[1][BAT]);  
620 -}  
621 -  
622 -static void VGA_printf (uint8_t *s)  
623 -{  
624 - uint16_t *arg_ptr;  
625 - unsigned int format_width, i;  
626 - int in_format;  
627 - uint16_t arg, digit, nibble;  
628 - uint8_t c;  
629 -  
630 - arg_ptr = (uint16_t *)((void *)&s);  
631 - in_format = 0;  
632 - format_width = 0;  
633 - while ((c = *s) != '\0') {  
634 - if (c == '%') {  
635 - in_format = 1;  
636 - format_width = 0;  
637 - } else if (in_format) {  
638 - if ((c >= '0') && (c <= '9')) {  
639 - format_width = (format_width * 10) + (c - '0');  
640 - } else if (c == 'x') {  
641 - arg_ptr++; // increment to next arg  
642 - arg = *arg_ptr;  
643 - if (format_width == 0)  
644 - format_width = 4;  
645 - digit = format_width - 1;  
646 - for (i = 0; i < format_width; i++) {  
647 - nibble = (arg >> (4 * digit)) & 0x000f;  
648 - if (nibble <= 9)  
649 - PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + '0');  
650 - else  
651 - PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + 'A');  
652 - digit--;  
653 - }  
654 - in_format = 0;  
655 - }  
656 - //else if (c == 'd') {  
657 - // in_format = 0;  
658 - // }  
659 - } else {  
660 - PPC_io_writeb(PPC_IO_BASE + 0x500, c);  
661 - }  
662 - s++;  
663 - }  
664 -}  
665 -  
666 -static void VGA_init (void)  
667 -{  
668 - /* Basic VGA init, inspired by plex86 VGAbios */  
669 -#if 1  
670 - /* switch to color mode and enable CPU access 480 lines */  
671 - PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3);  
672 - /* more than 64k 3C4/04 */  
673 - PPC_io_writeb(PPC_IO_BASE + 0x3C4, 0x04);  
674 - PPC_io_writeb(PPC_IO_BASE + 0x3C5, 0x02);  
675 -#endif  
676 - VGA_printf("PPC VGA BIOS...\n");  
677 -}  
678 -  
679 extern CPUPPCState *global_env; 405 extern CPUPPCState *global_env;
680 406
681 -static uint32_t get_le32 (void *addr)  
682 -{  
683 - return le32_to_cpu(*((uint32_t *)addr));  
684 -}  
685 -  
686 -void PPC_init_hw (/*CPUPPCState *env,*/ uint32_t mem_size,  
687 - uint32_t kernel_addr, uint32_t kernel_size,  
688 - uint32_t stack_addr, int boot_device,  
689 - const unsigned char *initrd_file)  
690 -{  
691 - CPUPPCState *env = global_env;  
692 - uint8_t *p;  
693 -#if !defined (USE_OPEN_FIRMWARE)  
694 - char *tmp;  
695 - uint32_t tmpi[2];  
696 -#endif  
697 -  
698 - printf("RAM size: %u 0x%08x (%u)\n", mem_size, mem_size, mem_size >> 20);  
699 -#if defined (USE_OPEN_FIRMWARE)  
700 - setup_memory(env, mem_size);  
701 -#endif  
702 -  
703 - /* Fake bootloader */  
704 - {  
705 -#if 1  
706 - uint32_t offset = get_le32(phys_ram_base + kernel_addr);  
707 -#else  
708 - uint32_t offset = 12;  
709 -#endif  
710 - env->nip = kernel_addr + offset;  
711 - printf("Start address: 0x%08x\n", env->nip);  
712 - }  
713 - /* Set up msr according to PREP specification */  
714 - msr_ee = 0;  
715 - msr_fp = 1;  
716 - msr_pr = 0; /* Start in supervisor mode */  
717 - msr_me = 1;  
718 - msr_fe0 = msr_fe1 = 0;  
719 - msr_ip = 0;  
720 - msr_ir = msr_dr = 1;  
721 -// msr_sf = 0;  
722 - msr_le = msr_ile = 0;  
723 - env->gpr[1] = stack_addr; /* Let's have a stack */  
724 - env->gpr[2] = 0;  
725 - env->gpr[8] = kernel_addr;  
726 - /* There is a bug in 2.4 kernels:  
727 - * if a decrementer exception is pending when it enables msr_ee,  
728 - * it's not ready to handle it...  
729 - */  
730 - p = phys_ram_base + kernel_addr;  
731 -#if !defined (USE_OPEN_FIRMWARE)  
732 - /* Let's register the whole memory available only in supervisor mode */  
733 - setup_BAT(env, 0, 0x00000000, 0x00000000, mem_size, 1, 0, 2);  
734 - /* Avoid open firmware init call (to get a console)  
735 - * This will make the kernel think we are a PREP machine...  
736 - */  
737 - put_long(p, 0xdeadc0de);  
738 - /* Build a real stack room */  
739 - p = phys_ram_base + stack_addr;  
740 - put_long(p, stack_addr);  
741 - p -= 32;  
742 - env->gpr[1] -= 32;  
743 - /* Pretend there are no residual data */  
744 - env->gpr[3] = 0;  
745 - if (initrd_file != NULL) {  
746 - int size;  
747 - env->gpr[4] = (kernel_addr + kernel_size + 4095) & ~4095;  
748 - size = load_initrd(initrd_file,  
749 - phys_ram_base + env->gpr[4]);  
750 - if (size < 0) {  
751 - /* No initrd */  
752 - env->gpr[4] = env->gpr[5] = 0;  
753 - } else {  
754 - env->gpr[5] = size;  
755 - boot_device = 'e';  
756 - }  
757 - printf("Initrd loaded at 0x%08x (%d) (0x%08x 0x%08x)\n",  
758 - env->gpr[4], env->gpr[5], kernel_addr, kernel_size);  
759 - } else {  
760 - env->gpr[4] = env->gpr[5] = 0;  
761 - }  
762 - /* We have to put bootinfos after the BSS  
763 - * The BSS starts after the kernel end.  
764 - */  
765 -#if 0  
766 - p = phys_ram_base + kernel_addr +  
767 - kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1);  
768 -#else  
769 - p = phys_ram_base + kernel_addr + 0x400000;  
770 -#endif  
771 - if (loglevel > 0) {  
772 - fprintf(logfile, "bootinfos: %p 0x%08x\n",  
773 - p, (int)(p - phys_ram_base));  
774 - } else {  
775 - printf("bootinfos: %p 0x%08x\n",  
776 - p, (int)(p - phys_ram_base));  
777 - }  
778 - /* Command line: let's put it after bootinfos */  
779 -#if 0  
780 - sprintf(p + 0x1000, "console=ttyS0,9600 root=%02x%02x mem=%dM",  
781 - boot_devs[boot_device - 'a'].major,  
782 - boot_devs[boot_device - 'a'].minor,  
783 - mem_size >> 20);  
784 -#else  
785 - sprintf(p + 0x1000, "console=ttyS0,9600 console=tty0 root=%s mem=%dM",  
786 - boot_devs[boot_device - 'a'].name,  
787 - mem_size >> 20);  
788 -#endif  
789 - env->gpr[6] = p + 0x1000 - phys_ram_base;  
790 - env->gpr[7] = env->gpr[6] + strlen(p + 0x1000);  
791 - if (loglevel > 0) {  
792 - fprintf(logfile, "cmdline: %p 0x%08x [%s]\n",  
793 - p + 0x1000, env->gpr[6], p + 0x1000);  
794 - } else {  
795 - printf("cmdline: %p 0x%08x [%s]\n",  
796 - p + 0x1000, env->gpr[6], p + 0x1000);  
797 - }  
798 - /* BI_FIRST */  
799 - p = set_bootinfo_tag(p, 0x1010, 0, 0);  
800 - /* BI_CMD_LINE */  
801 - p = set_bootinfo_tag(p, 0x1012, env->gpr[7] - env->gpr[6],  
802 - env->gpr[6] + phys_ram_base);  
803 - /* BI_MEM_SIZE */  
804 - tmp = (void *)tmpi;  
805 - tmp[0] = (mem_size >> 24) & 0xFF;  
806 - tmp[1] = (mem_size >> 16) & 0xFF;  
807 - tmp[2] = (mem_size >> 8) & 0xFF;  
808 - tmp[3] = mem_size & 0xFF;  
809 - p = set_bootinfo_tag(p, 0x1017, 4, tmpi);  
810 - /* BI_INITRD */  
811 - tmp[0] = (env->gpr[4] >> 24) & 0xFF;  
812 - tmp[1] = (env->gpr[4] >> 16) & 0xFF;  
813 - tmp[2] = (env->gpr[4] >> 8) & 0xFF;  
814 - tmp[3] = env->gpr[4] & 0xFF;  
815 - tmp[4] = (env->gpr[5] >> 24) & 0xFF;  
816 - tmp[5] = (env->gpr[5] >> 16) & 0xFF;  
817 - tmp[6] = (env->gpr[5] >> 8) & 0xFF;  
818 - tmp[7] = env->gpr[5] & 0xFF;  
819 - p = set_bootinfo_tag(p, 0x1014, 8, tmpi);  
820 - env->gpr[4] = env->gpr[5] = 0;  
821 - /* BI_LAST */  
822 - p = set_bootinfo_tag(p, 0x1011, 0, 0);  
823 -#else  
824 - /* Set up MMU:  
825 - * kernel is loaded at kernel_addr and wants to be seen at 0x01000000  
826 - */  
827 - setup_BAT(env, 0, 0x01000000, kernel_addr, 0x00400000, 1, 0, 2);  
828 - {  
829 -#if 0  
830 - uint32_t offset = get_le32(phys_ram_base + kernel_addr);  
831 -#else  
832 - uint32_t offset = 12;  
833 -#endif  
834 - env->nip = 0x01000000 | (kernel_addr + offset);  
835 - printf("Start address: 0x%08x\n", env->nip);  
836 - }  
837 - env->gpr[1] = env->nip + (1 << 22);  
838 - p = phys_ram_base + stack_addr;  
839 - put_long(p - 32, stack_addr);  
840 - env->gpr[1] -= 32;  
841 - printf("Kernel starts at 0x%08x stack 0x%08x\n", env->nip, env->gpr[1]);  
842 - /* We want all lower address not to be translated */  
843 - setup_BAT(env, 1, 0x00000000, 0x00000000, 0x010000000, 1, 1, 2);  
844 - /* We also need a BAT to access OF */  
845 - setup_BAT(env, 2, 0xFFFE0000, mem_size - 131072, 131072, 1, 0, 1);  
846 - /* Setup OF entry point */  
847 - {  
848 - char *p;  
849 - p = (char *)phys_ram_base + mem_size - 131072;  
850 - /* Special opcode to call OF */  
851 - *p++ = 0x18; *p++ = 0x00; *p++ = 0x00; *p++ = 0x02;  
852 - /* blr */  
853 - *p++ = 0x4E; *p++ = 0x80; *p++ = 0x00; *p++ = 0x20;  
854 - }  
855 - env->gpr[5] = 0xFFFE0000;  
856 - /* Register translations */  
857 - {  
858 - OF_transl_t translations[3] = {  
859 - { 0x01000000, 0x00400000, kernel_addr, 0x00000002, },  
860 - { 0x00000000, 0x01000000, 0x00000000, 0x00000002, },  
861 - { 0xFFFE0000, 0x00020000, mem_size - (128 * 1024),  
862 - 0x00000001, },  
863 - };  
864 - OF_register_translations(3, translations);  
865 - }  
866 - /* Quite artificial, for now */  
867 - OF_register_bus("isa", "isa");  
868 - OF_register_serial("isa", "serial", 4, 0x3f8);  
869 - OF_register_stdio("serial", "serial");  
870 - /* Set up RTAS service */  
871 - RTAS_init();  
872 - /* Command line: let's put it just over the stack */  
873 -#if 0  
874 -#if 0  
875 - p = phys_ram_base + kernel_addr +  
876 - kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1);  
877 -#else  
878 - p = phys_ram_base + kernel_addr + 0x400000;  
879 -#endif  
880 -#if 1  
881 - sprintf(p, "console=ttyS0,9600 root=%02x%02x mem=%dM",  
882 - boot_devs[boot_device - 'a'].major,  
883 - boot_devs[boot_device - 'a'].minor,  
884 - mem_size >> 20);  
885 -#else  
886 - sprintf(p, "console=ttyS0,9600 root=%s mem=%dM ne2000=0x300,9",  
887 - boot_devs[boot_device - 'a'].name,  
888 - mem_size >> 20);  
889 -#endif  
890 - OF_register_bootargs(p);  
891 -#endif  
892 -#endif  
893 -}  
894 -  
895 -void PPC_end_init (void)  
896 -{  
897 - VGA_init();  
898 -} 407 +#define NVRAM_SIZE 0x2000
899 408
900 /* PowerPC PREP hardware initialisation */ 409 /* PowerPC PREP hardware initialisation */
901 void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, 410 void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
@@ -904,56 +413,63 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, @@ -904,56 +413,63 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
904 const char *initrd_filename) 413 const char *initrd_filename)
905 { 414 {
906 char buf[1024]; 415 char buf[1024];
  416 + // void *openpic;
  417 + m48t59_t *nvram;
907 int PPC_io_memory; 418 int PPC_io_memory;
908 - int ret, linux_boot, initrd_size, i, nb_nics1, fd; 419 + int ret, linux_boot, i, nb_nics1, fd;
  420 + unsigned long bios_offset;
  421 + uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  422 +
  423 + sysctrl = qemu_mallocz(sizeof(sysctrl_t));
  424 + if (sysctrl == NULL)
  425 + return;
909 426
910 linux_boot = (kernel_filename != NULL); 427 linux_boot = (kernel_filename != NULL);
911 428
912 /* allocate RAM */ 429 /* allocate RAM */
913 - cpu_register_physical_memory(0, ram_size, 0);  
914 -  
915 - isa_mem_base = 0xc0000000; 430 + cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
  431 +
  432 + /* allocate and load BIOS */
  433 + bios_offset = ram_size + vga_ram_size;
  434 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  435 + ret = load_image(buf, phys_ram_base + bios_offset);
  436 + if (ret != BIOS_SIZE) {
  437 + fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
  438 + exit(1);
  439 + }
  440 + cpu_register_physical_memory((uint32_t)(-BIOS_SIZE),
  441 + BIOS_SIZE, bios_offset | IO_MEM_ROM);
  442 + cpu_single_env->nip = 0xfffffffc;
916 443
917 if (linux_boot) { 444 if (linux_boot) {
  445 + kernel_base = KERNEL_LOAD_ADDR;
918 /* now we can load the kernel */ 446 /* now we can load the kernel */
919 - ret = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);  
920 - if (ret < 0) { 447 + kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
  448 + if (kernel_size < 0) {
921 fprintf(stderr, "qemu: could not load kernel '%s'\n", 449 fprintf(stderr, "qemu: could not load kernel '%s'\n",
922 kernel_filename); 450 kernel_filename);
923 exit(1); 451 exit(1);
924 } 452 }
925 /* load initrd */ 453 /* load initrd */
926 - initrd_size = 0;  
927 -#if 0  
928 if (initrd_filename) { 454 if (initrd_filename) {
929 - initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); 455 + initrd_base = INITRD_LOAD_ADDR;
  456 + initrd_size = load_image(initrd_filename,
  457 + phys_ram_base + initrd_base);
930 if (initrd_size < 0) { 458 if (initrd_size < 0) {
931 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 459 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
932 initrd_filename); 460 initrd_filename);
933 exit(1); 461 exit(1);
934 } 462 }
  463 + } else {
  464 + initrd_base = 0;
  465 + initrd_size = 0;
935 } 466 }
936 -#endif  
937 - PPC_init_hw(/*env,*/ ram_size, KERNEL_LOAD_ADDR, ret,  
938 - KERNEL_STACK_ADDR, boot_device, initrd_filename); 467 + boot_device = 'm';
939 } else { 468 } else {
940 - int bios_ram_offset;  
941 -  
942 -#define BIOS_START 0x00800000  
943 -  
944 - /* allocate ROM */  
945 - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);  
946 - bios_ram_offset = ram_size + vga_ram_size;  
947 - printf("load BIOS at 0x%08x\n", BIOS_START);  
948 - ret = load_image(buf, phys_ram_base + bios_ram_offset);  
949 - if (ret != BIOS_SIZE) {  
950 - fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",  
951 - buf, ret);  
952 - exit(1);  
953 - }  
954 - global_env->nip = BIOS_START + BIOS_SIZE - 4;  
955 - cpu_register_physical_memory(BIOS_START, BIOS_SIZE,  
956 - IO_MEM_ROM | bios_ram_offset); 469 + kernel_base = 0;
  470 + kernel_size = 0;
  471 + initrd_base = 0;
  472 + initrd_size = 0;
957 } 473 }
958 474
959 /* Register CPU as a 74x/75x */ 475 /* Register CPU as a 74x/75x */
@@ -961,50 +477,78 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, @@ -961,50 +477,78 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
961 /* Set time-base frequency to 100 Mhz */ 477 /* Set time-base frequency to 100 Mhz */
962 cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); 478 cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
963 479
  480 + isa_mem_base = 0xc0000000;
  481 + pci_prep_init();
  482 + /* Register 64 KB of ISA IO space */
  483 + PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
  484 + cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory);
  485 +
964 /* init basic PC hardware */ 486 /* init basic PC hardware */
965 vga_initialize(ds, phys_ram_base + ram_size, ram_size, 487 vga_initialize(ds, phys_ram_base + ram_size, ram_size,
966 - vga_ram_size, 0); 488 + vga_ram_size, 1);
967 rtc_init(0x70, 8); 489 rtc_init(0x70, 8);
  490 + // openpic = openpic_init(0x00000000, 0xF0000000, 1);
  491 + // pic_init(openpic);
968 pic_init(); 492 pic_init();
969 - // pit_init(0x40, 0); 493 + // pit = pit_init(0x40, 0);
970 494
971 fd = serial_open_device(); 495 fd = serial_open_device();
972 serial_init(0x3f8, 4, fd); 496 serial_init(0x3f8, 4, fd);
973 -#if 1  
974 nb_nics1 = nb_nics; 497 nb_nics1 = nb_nics;
975 if (nb_nics1 > NE2000_NB_MAX) 498 if (nb_nics1 > NE2000_NB_MAX)
976 nb_nics1 = NE2000_NB_MAX; 499 nb_nics1 = NE2000_NB_MAX;
977 for(i = 0; i < nb_nics1; i++) { 500 for(i = 0; i < nb_nics1; i++) {
978 isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); 501 isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
979 } 502 }
980 -#endif  
981 503
982 for(i = 0; i < 2; i++) { 504 for(i = 0; i < 2; i++) {
983 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], 505 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
984 bs_table[2 * i], bs_table[2 * i + 1]); 506 bs_table[2 * i], bs_table[2 * i + 1]);
985 } 507 }
986 kbd_init(); 508 kbd_init();
987 - AUD_init();  
988 DMA_init(); 509 DMA_init();
  510 + // AUD_init();
989 // SB16_init(); 511 // SB16_init();
990 512
991 fdctrl_init(6, 2, 0, 0x3f0, fd_table); 513 fdctrl_init(6, 2, 0, 0x3f0, fd_table);
992 514
993 - /* Register 64 kB of IO space */  
994 - PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);  
995 - cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory); 515 + /* Register speaker port */
  516 + register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
  517 + register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
996 /* Register fake IO ports for PREP */ 518 /* Register fake IO ports for PREP */
997 - register_ioport_read(0x398, 2, 1, &PREP_io_read, NULL);  
998 - register_ioport_write(0x398, 2, 1, &PREP_io_write, NULL); 519 + register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
  520 + register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
999 /* System control ports */ 521 /* System control ports */
1000 - register_ioport_write(0x0092, 0x1, 1, &PREP_io_800_writeb, NULL);  
1001 - register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, NULL);  
1002 - register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, NULL);  
1003 - /* PCI intack location (0xfef00000 / 0xbffffff0) */  
1004 - PPC_io_memory = cpu_register_io_memory(0, PPC_ioB_read, PPC_ioB_write); 522 + register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
  523 + register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
  524 + register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
  525 + register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
  526 + /* PCI intack location */
  527 + PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
  528 + PPC_intack_write);
1005 cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory); 529 cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
1006 - // cpu_register_physical_memory(0xFEF00000, 0x4, PPC_io_memory);  
1007 - prep_NVRAM_init(); 530 + /* PowerPC control and status register group */
  531 + PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write);
  532 + cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
1008 533
1009 - PPC_end_init(); 534 + nvram = m48t59_init(8, 0x0074, NVRAM_SIZE);
  535 + if (nvram == NULL)
  536 + return;
  537 + sysctrl->nvram = nvram;
  538 +
  539 + /* Initialise NVRAM */
  540 + PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
  541 + kernel_base, kernel_size,
  542 + (uint32_t)(long)kernel_cmdline,
  543 + strlen(kernel_cmdline),
  544 + initrd_base, initrd_size,
  545 + /* XXX: need an option to load a NVRAM image */
  546 + 0
  547 + );
  548 +
  549 + /* Special port to get debug messages from Open-Firmware */
  550 + register_ioport_write(0xFF00, 0x04, 1, &PREP_debug_write, NULL);
  551 + register_ioport_write(0xFF00, 0x04, 2, &PREP_debug_write, NULL);
  552 +
  553 + pci_ppc_bios_init();
1010 } 554 }
@@ -594,15 +594,34 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, @@ -594,15 +594,34 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
594 const char *kernel_filename, const char *kernel_cmdline, 594 const char *kernel_filename, const char *kernel_cmdline,
595 const char *initrd_filename); 595 const char *initrd_filename);
596 ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq); 596 ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
597 -struct sysctrl_t;  
598 -int prep_NVRAM_init (struct sysctrl_t *sysctrl, uint32_t RAM_size,  
599 - uint32_t BIOS_size, int boot_device,  
600 - uint32_t kernel_image); 597 +void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
601 598
602 extern CPUWriteMemoryFunc *PPC_io_write[]; 599 extern CPUWriteMemoryFunc *PPC_io_write[];
603 extern CPUReadMemoryFunc *PPC_io_read[]; 600 extern CPUReadMemoryFunc *PPC_io_read[];
604 extern int prep_enabled; 601 extern int prep_enabled;
605 602
  603 +/* NVRAM helpers */
  604 +#include "hw/m48t59.h"
  605 +
  606 +void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);
  607 +uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);
  608 +void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);
  609 +uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);
  610 +void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);
  611 +uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);
  612 +void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
  613 + const unsigned char *str, uint32_t max);
  614 +int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);
  615 +void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,
  616 + uint32_t start, uint32_t count);
  617 +int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
  618 + const unsigned char *arch,
  619 + uint32_t RAM_size, int boot_device,
  620 + uint32_t kernel_image, uint32_t kernel_size,
  621 + uint32_t cmdline, uint32_t cmdline_size,
  622 + uint32_t initrd_image, uint32_t initrd_size,
  623 + uint32_t NVRAM_image);
  624 +
606 /* monitor.c */ 625 /* monitor.c */
607 void monitor_init(void); 626 void monitor_init(void);
608 void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2))); 627 void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));