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 244 VL_OBJS+= ppc.o
245 245 # PREP hardware support
246 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 249 endif
250 250 ifdef CONFIG_GDBSTUB
251 251 VL_OBJS+=gdbstub.o
... ...
hw/ppc.c
... ... @@ -23,11 +23,6 @@
23 23 */
24 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 27 /* PPC time base and decrementer emulation */
33 28 //#define DEBUG_TB
... ... @@ -202,14 +197,249 @@ void cpu_ppc_reset (CPUState *env)
202 197 }
203 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 431 void ppc_init (int ram_size, int vga_ram_size, int boot_device,
207 432 DisplayState *ds, const char **fd_filename, int snapshot,
208 433 const char *kernel_filename, const char *kernel_cmdline,
209 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 22 * THE SOFTWARE.
23 23 */
24 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 26 //#define HARD_DEBUG_PPC_IO
31 27 //#define DEBUG_PPC_IO
32 28  
  29 +#define KERNEL_LOAD_ADDR 0x01000000;
  30 +#define INITRD_LOAD_ADDR 0x01800000;
  31 +
33 32 extern int loglevel;
34 33 extern FILE *logfile;
35 34  
... ... @@ -58,42 +57,7 @@ do { \
58 57 #endif
59 58  
60 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 61 static const int ide_iobase[2] = { 0x1f0, 0x170 };
98 62 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
99 63 static const int ide_irq[2] = { 13, 13 };
... ... @@ -103,218 +67,300 @@ static const int ide_irq[2] = { 13, 13 };
103 67 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
104 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 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 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 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 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 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 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 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 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 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 187 #ifdef TARGET_WORDS_BIGENDIAN
174   - value = bswap32(value);
  188 + value = bswap16(value);
175 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 195 #ifdef TARGET_WORDS_BIGENDIAN
184   - ret = bswap32(ret);
  196 + value = bswap32(value);
185 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 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 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 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 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 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 282 switch (addr) {
267 283 case 0x0092:
268 284 /* Special port 92 */
269 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 289 /* Check LE mode */
275   - if (val & 0x40) {
  290 + if (val & 0x02) {
276 291 printf("Little Endian mode isn't supported (yet ?)\n");
277 292 abort();
278 293 }
279 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 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 310 break;
283 311 case 0x0810:
284 312 /* Password protect 1 register */
285   - NVRAM_lock ^= 0x01;
  313 + if (sysctrl->nvram != NULL)
  314 + m48t59_toggle_lock(sysctrl->nvram, 1);
286 315 break;
287 316 case 0x0812:
288 317 /* Password protect 2 register */
289   - NVRAM_lock ^= 0x02;
  318 + if (sysctrl->nvram != NULL)
  319 + m48t59_toggle_lock(sysctrl->nvram, 2);
290 320 break;
291 321 case 0x0814:
292   - /* L2 invalidate register: don't care */
  322 + /* L2 invalidate register */
  323 + // tlb_flush(cpu_single_env, 1);
293 324 break;
294 325 case 0x081C:
295 326 /* system control register */
296   - syscontrol = val;
  327 + sysctrl->syscontrol = val & 0x0F;
297 328 break;
298 329 case 0x0850:
299 330 /* I/O map type register */
300   - if (val & 0x80) {
  331 + if (!(val & 0x01)) {
301 332 printf("No support for non-continuous I/O map mode\n");
302 333 abort();
303 334 }
304 335 break;
305 336 default:
  337 + printf("ERROR: unaffected IO port write: %04lx => %02x\n",
  338 + (long)addr, val);
306 339 break;
307 340 }
308 341 }
309 342  
310 343 static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
311 344 {
  345 + sysctrl_t *sysctrl = opaque;
312 346 uint32_t retval = 0xFF;
313 347  
314 348 switch (addr) {
315 349 case 0x0092:
316 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 364 break;
319 365 case 0x080C:
320 366 /* Equipment present register:
... ... @@ -323,7 +369,11 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
323 369 * no cards in PCI slots
324 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 377 break;
328 378 case 0x0818:
329 379 /* Keylock */
... ... @@ -333,7 +383,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
333 383 /* system control register
334 384 * 7 - 6 / 1 - 0: L2 cache enable
335 385 */
336   - retval = syscontrol;
  386 + retval = sysctrl->syscontrol;
337 387 break;
338 388 case 0x0823:
339 389 /* */
... ... @@ -341,561 +391,20 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
341 391 break;
342 392 case 0x0850:
343 393 /* I/O map type register */
344   - retval = 0x00;
  394 + retval = 0x01;
345 395 break;
346 396 default:
  397 + printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
347 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 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 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 409 /* PowerPC PREP hardware initialisation */
901 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 413 const char *initrd_filename)
905 414 {
906 415 char buf[1024];
  416 + // void *openpic;
  417 + m48t59_t *nvram;
907 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 427 linux_boot = (kernel_filename != NULL);
911 428  
912 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 444 if (linux_boot) {
  445 + kernel_base = KERNEL_LOAD_ADDR;
918 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 449 fprintf(stderr, "qemu: could not load kernel '%s'\n",
922 450 kernel_filename);
923 451 exit(1);
924 452 }
925 453 /* load initrd */
926   - initrd_size = 0;
927   -#if 0
928 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 458 if (initrd_size < 0) {
931 459 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
932 460 initrd_filename);
933 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 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 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 477 /* Set time-base frequency to 100 Mhz */
962 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 486 /* init basic PC hardware */
965 487 vga_initialize(ds, phys_ram_base + ram_size, ram_size,
966   - vga_ram_size, 0);
  488 + vga_ram_size, 1);
967 489 rtc_init(0x70, 8);
  490 + // openpic = openpic_init(0x00000000, 0xF0000000, 1);
  491 + // pic_init(openpic);
968 492 pic_init();
969   - // pit_init(0x40, 0);
  493 + // pit = pit_init(0x40, 0);
970 494  
971 495 fd = serial_open_device();
972 496 serial_init(0x3f8, 4, fd);
973   -#if 1
974 497 nb_nics1 = nb_nics;
975 498 if (nb_nics1 > NE2000_NB_MAX)
976 499 nb_nics1 = NE2000_NB_MAX;
977 500 for(i = 0; i < nb_nics1; i++) {
978 501 isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
979 502 }
980   -#endif
981 503  
982 504 for(i = 0; i < 2; i++) {
983 505 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
984 506 bs_table[2 * i], bs_table[2 * i + 1]);
985 507 }
986 508 kbd_init();
987   - AUD_init();
988 509 DMA_init();
  510 + // AUD_init();
989 511 // SB16_init();
990 512  
991 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 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 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 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 594 const char *kernel_filename, const char *kernel_cmdline,
595 595 const char *initrd_filename);
596 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 599 extern CPUWriteMemoryFunc *PPC_io_write[];
603 600 extern CPUReadMemoryFunc *PPC_io_read[];
604 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 625 /* monitor.c */
607 626 void monitor_init(void);
608 627 void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
... ...