summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openhackware/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openhackware/src/main.c')
-rw-r--r--qemu/roms/openhackware/src/main.c564
1 files changed, 0 insertions, 564 deletions
diff --git a/qemu/roms/openhackware/src/main.c b/qemu/roms/openhackware/src/main.c
deleted file mode 100644
index 2d61d64ff..000000000
--- a/qemu/roms/openhackware/src/main.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Open Hack'Ware BIOS main.
- *
- * Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License V2
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Status:
- * - boots Linux 2.4 from floppy and IDE
- * - preliminary residual data support
- * - can find PREP boot images and Apple boot blocs
- *
- * TODO:
- * 1/ Cleanify boot partitions:
- * allow more than one boot bloc + fix PREP load again
- * 2/ add ATAPI driver
- * 3/ add a prompt to let the user choose its boot device / PREP image
- * 4/ add POST
- * 5/ add VGA driver (SVGA/VESA ?)
- * 6/ add a user accessible setup
- * 7/ add netboot
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "bios.h"
-
-#include "char.h"
-
-//#define DEBUG_MEMORY 1
-
-/* Version string */
-const unsigned char *BIOS_str =
-"PPC Open Hack'Ware BIOS for qemu version " BIOS_VERSION "\n";
-const unsigned char *copyright = "Copyright 2003-2005 Jocelyn Mayer\n";
-
-uint32_t isa_io_base = ISA_IO_BASE;
-
-/* Temporary hack: boots only from floppy */
-int boot_device = 'a';
-
-/* Some other PPC helper */
-/* Setup a memory mapping, using BAT0
- * BATU:
- * BEPI : bloc virtual address
- * BL : area size bits (128 kB is 0, 256 1, 512 3, ...
- * Vs/Vp
- * BATL:
- * BPRN : bloc real address align on 4MB boundary
- * WIMG : cache access mode : not used
- * PP : protection bits
- */
-static void BAT_setup (int nr, uint32_t virtual, uint32_t physical,
- uint32_t size, int Vs, int Vp, int PP)
-{
- uint32_t sz_bits, tmp_sz, align, tmp;
-
- sz_bits = 0;
- align = 131072;
- DPRINTF("Set BAT %d v=%0x p=%0x size=%0x\n", nr, virtual, physical, size);
- if (size < 131072)
- size = 131072;
- for (tmp_sz = size / 131072; tmp_sz != 1; tmp_sz = tmp_sz >> 1) {
- sz_bits = (sz_bits << 1) + 1;
- align = align << 1;
- }
- tmp = virtual & ~(align - 1); /* Align virtual area start */
- tmp |= sz_bits << 2; /* Fix BAT size */
- tmp |= Vs << 1; /* Supervisor access */
- tmp |= Vp; /* User access */
- DPRINTF("Set BATU%d to %0x\n", nr, tmp);
- switch (nr) {
- case 0:
- /* Setup IBAT0U */
- MTSPR(528, tmp);
- /* Setup DBAT0U */
- MTSPR(536, tmp);
- break;
- case 1:
- /* Setup DBAT1U */
- MTSPR(538, tmp);
- break;
- case 2:
- /* Setup DBAT2U */
- MTSPR(540, tmp);
- break;
- }
- tmp = physical & ~(align - 1); /* Align physical area start */
- tmp |= 0; /* Don't care about WIMG */
- tmp |= PP; /* Protection */
- DPRINTF("Set BATL%d to %0x\n", nr, tmp);
- switch (nr) {
- case 0:
- /* Setup IBAT0L */
- MTSPR(529, tmp);
- /* Setup DBAT0L */
- MTSPR(537, tmp);
- break;
- case 1:
- /* Setup DBAT1L */
- MTSPR(539, tmp);
- break;
- case 2:
- /* Setup DBAT2L */
- MTSPR(541, tmp);
- break;
- }
-}
-
-typedef struct PPC_CPU_t {
- uint32_t pvr;
- uint32_t mask;
- unsigned char *name;
-} PPC_CPU_t;
-
-static const PPC_CPU_t CPU_PPC[] = {
- /* For now, know only G3 */
- {
- 0x00080000,
- 0xFFFF0000,
- "PowerPC,G3",
- },
- {
- 0x00000000,
- 0x00000000,
- "PowerPC,generic",
- },
-};
-
-static const unsigned char *CPU_get_name (uint32_t pvr)
-{
- int i;
-
- for (i = 0;; i++) {
- if ((pvr & CPU_PPC[i].mask) == CPU_PPC[i].pvr)
- return CPU_PPC[i].name;
- }
-
- return NULL;
-}
-
-#define TB_FREQ (10 * 1000 * 1000) // XXX: should calibrate
-void usleep (uint32_t usec)
-{
-#if 0 // Buggy: makes OpenDarwin crash (!)
- uint32_t tb0[2], tb1[2], count[2];
- uint32_t tpu;
- int wrap = 0;
-
- tpu = TB_FREQ / (1000 * 1000);
- mul64(count, usec, tpu);
- mftb(tb0);
- add64(count, count, tb0);
- if (count[0] < tb0[0])
- wrap = 1;
- while (1) {
- mftb(tb1);
- if (wrap == 1 && tb1[0] < tb0[0])
- wrap = 0;
- if (wrap == 0 &&
- (tb1[0] > count[0] ||
- (tb1[0] == count[0] && tb1[1] >= count[1])))
- break;
- tb0[0] = tb1[0];
- }
-#else
- uint32_t i, j;
-
- for (i = 0; i < (usec >> 16) * 50; i++) {
- for (j = 0; j < (usec & 0xFFFF) * 50; j++) {
- continue;
- }
- }
-#endif
-}
-
-void sleep (int sec)
-{
- int i;
-
- for (i = 0; i < sec; i++)
- usleep(1 * 1000 * 1000);
-}
-
-/* Stolen from Linux code */
-#define CRCPOLY_LE 0xedb88320
-
-uint32_t crc32 (uint32_t crc, const uint8_t *p, int len)
-{
- int i;
-
- while (len--) {
- crc ^= *p++;
- for (i = 0; i < 8; i++)
- crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
- }
-
- return crc;
-}
-
-/* Fake write */
-int write (unused int fd, unused const char *buf, int len)
-{
- return len;
-}
-
-/* BIOS library functions */
-/* Fake memory management (to be removed) */
-void *mem_align (unused int align)
-{
- return malloc(0);
-}
-#if 1
-void free (unused void *p)
-{
-}
-#endif
-
-void freep (void *p)
-{
- void **_p = p;
-
- free(*_p);
- *_p = NULL;
-}
-
-static inline int in_area (const void *buf,
- const void *start, const void *end)
-{
- return buf >= start && buf <= end;
-}
-
-#ifdef DEBUG_MEMORY
-static void *load_dest, *load_end;
-static int relax_check;
-#endif
-
-void set_loadinfo (unused void *load_base, unused uint32_t size)
-{
-#ifdef DEBUG_MEMORY
- load_dest = load_base;
- load_end = (char *)load_dest + size;
-#endif
-}
-
-void set_check (unused int do_it)
-{
-#ifdef DEBUG_MEMORY
- relax_check = do_it == 0 ? 1 : 0;
-#endif
-}
-
-void check_location (unused const void *buf,
- unused const char *func,
- unused const char *name)
-{
-#ifdef DEBUG_MEMORY
- if (relax_check != 0)
- return;
- if (!in_area(buf, &_data_start, &_data_end) &&
- !in_area(buf, &_OF_vars_start, &_OF_vars_end) &&
- !in_area(buf, &_sdata_start, &_sdata_end) &&
- !in_area(buf, &_ro_start, &_ro_end) &&
- !in_area(buf, &_RTAS_data_start, &_RTAS_data_end) &&
- !in_area(buf, &_bss_start, &_bss_end) &&
- !in_area(buf, &_ram_start, malloc_base) &&
- /* Let's say 64 kB of stack is enough */
- !in_area(buf, (void *)0x5ff0000, (void *)0x6000000) &&
- !in_area(buf, load_dest, load_end) &&
- /* IO area */
- !in_area(buf, (void *)0x80000000, (void *)0x88000000)) {
- printf("**************************************************************"
- "**************\n");
- printf("%s: %s: %p\n", func, name, buf);
- printf(" data: %p %p\n", &_data_start, &_data_end);
- printf(" OF_vars: %p %p\n", &_OF_vars_start, &_OF_vars_end);
- printf(" sdata: %p %p\n", &_sdata_start, &_sdata_end);
- printf(" rodata: %p %p\n", &_ro_start, &_ro_end);
- printf(" RTAS_data: %p %p\n", &_RTAS_data_start, &_RTAS_data_end);
- printf(" bss: %p %p\n", &_bss_start, &_bss_end);
- printf(" mallocated: %p %p\n", &_ram_start, malloc_base);
- printf(" stack : %p %p\n", (void *)0x5ff0000,
- (void *)0x6000000);
- printf(" load image: %p %p\n", load_dest, load_end);
- printf("**************************************************************"
- "**************\n");
- bug();
- }
-#endif
-}
-
-/* No overflow check here... */
-long strtol (const unsigned char *str, unsigned char **end, int base)
-{
- long ret = 0, tmp, sign = 1;
-
- check_location(str, __func__, "str");
- if (base < 0 || base > 36)
- return 0;
- for (; *str == ' '; str++)
- continue;
- if (*str == '-') {
- sign = -1;
- str++;
- }
- for (;; str++) {
- tmp = *str;
- if (tmp < '0')
- break;
- if (base <= 10) {
- if (tmp > '0' + base - 1)
- break;
- tmp -= '0';
- } else {
- if (tmp <= '9') {
- tmp -= '0';
- } else {
- tmp &= ~0x20;
- if (tmp < 'A' || tmp > 'A' + base - 11)
- break;
- tmp += 10 - 'A';
- }
- }
- ret = (ret * base) + tmp;
- }
- if (sign == -1)
- ret = -ret;
- if (end != NULL)
- *end = (unsigned char *)str;
-
- return ret;
-}
-
-nvram_t *nvram;
-int arch;
-/* HACK... */
-int vga_width, vga_height, vga_depth;
-
-part_t *boot_part;
-
-/* XXX: to fix */
-void mm_init (uint32_t memsize);
-int page_descrs_init (void);
-
-int main (void)
-{
- bloc_device_t *bd;
- pci_host_t *pci_main;
- void *res, *bootinfos;
- void *boot_image, *cmdline, *ramdisk;
- void *load_base, *load_entry, *last_alloc, *load_end;
- uint32_t memsize, boot_image_size, cmdline_size, ramdisk_size;
- uint32_t boot_nb;
- int boot_device, i;
- static const uint32_t isa_base_tab[3] = {
- 0x80000000, /* PREP */
- 0xFE000000, /* Grackle (Heathrow) */
- 0xF2000000, /* UniNorth (Mac99) */
- };
-
- /* Retrieve NVRAM configuration */
- for(i = 0; i < 3; i++) {
- isa_io_base = isa_base_tab[i];
- nvram = NVRAM_get_config(&memsize, &boot_device,
- &boot_image, &boot_image_size,
- &cmdline, &cmdline_size,
- &ramdisk, &ramdisk_size);
- if (nvram)
- break;
- }
- if (i == 3) {
- ERROR("Unable to load configuration from NVRAM. Aborting...\n");
- return -1;
- }
-#if 1
- mm_init(memsize);
-#endif
-#if 1
- page_descrs_init();
-#endif
-#ifdef USE_OPENFIRMWARE
- OF_init();
-#endif
- pci_main = pci_init();
- if (pci_main == NULL)
- ERROR("Unable to configure PCI\n");
-#ifdef USE_OPENFIRMWARE
- /* XXX: this mess needs a serious cleanup... */
- {
- const unsigned char *cpu_name;
- uint32_t pvr = mfpvr();
-
- cpu_name = CPU_get_name(pvr);
- OF_register_cpu(cpu_name, 0, pvr,
- 200 * 1000 * 1000, 200 * 1000 * 1000,
- 100 * 1000 * 1000, 100 * 1000 * 1000,
- 0x0092);
- }
- OF_register_memory(memsize, 512 * 1024 /* TOFIX */);
- /* Claim memory used by the BIOS */
- OF_claim_virt(0x05800000, 0x00080000, NULL);
- OF_register_bootargs(cmdline);
-#endif
- if (isa_io_base == 0x80000000 || 1) {
- pc_serial_register(0x3F8);
-#ifdef USE_OPENFIRMWARE
- OF_register_bus("isa", isa_io_base, "ISA");
- OF_register_serial("isa", "com1", 0x3F8, 4);
- OF_register_stdio("com1", "com1");
-#endif
- }
-#ifdef USE_OPENFIRMWARE
- RTAS_init();
-#endif
- /* Get a console */
- console_open();
- printf("%s", BIOS_str);
- printf("Build " stringify(BUILD_DATE) " " stringify(BUILD_TIME) "\n");
- printf("%s\n", copyright);
- printf("Memory size: %d MB. \nBooting from device %c\n",
- memsize >> 20, boot_device);
- vga_puts(BIOS_str);
- vga_puts("Build " stringify(BUILD_DATE) " " stringify(BUILD_TIME) "\n");
- vga_puts(copyright);
- vga_puts("\n");
-
-#if 0
- /* QEMU is quite incoherent: d is cdrom, not second drive */
- /* XXX: should probe CD-ROM position */
- if (boot_device == 'd')
- boot_device = 'e';
-#endif
- /* Open boot device */
- boot_part = bd_probe(boot_device);
- if (boot_device == 'm') {
- bd = bd_get('m');
- if (bd == NULL) {
- ERROR("Unable to get memory bloc device\n");
- return -1;
- }
- printf("boot device: %p image %p size %d\n",
- bd, boot_image, boot_image_size);
- bd_ioctl(bd, MEM_SET_ADDR, boot_image);
- bd_ioctl(bd, MEM_SET_SIZE, &boot_image_size);
- boot_part = part_probe(bd, 1);
- bd_put(bd);
- printf("boot device: %p\n", bd);
- }
- if (boot_part == NULL) {
- ERROR("Found no boot partition!\n");
- return -1;
- }
- ERROR("Found boot partition : %p %p\n", boot_part, part_fs(boot_part));
- mem_align(0x00001000);
- res = malloc(0x4000);
- last_alloc = malloc(0);
- boot_nb = 0;
- DPRINTF("Load base: %p - residual data: %p %p %p %p\n",
- load_base, res, last_alloc, boot_part, part_fs(boot_part));
- /* Load the whole boot image */
- if (bootfile_load((void *)&load_base, (void *)&load_entry,
- (void *)&load_end, boot_part, -1, NULL, 0) < 0) {
- printf("Unable to load boot file\n");
- return -1;
- }
-#ifdef USE_OPENFIRMWARE
- DPRINTF("Boot parameters: res: %p load_base: %p OF: %p entry: %p\n",
- res, load_base, &OF_entry, load_entry);
-#else
- DPRINTF("Boot parameters: res: %p load_base: %p OF: %p entry: %p\n",
- res, load_base, NULL, load_entry);
-#endif
- DPRINTF("Boot: %0x %0x %0x %0x\n", *(uint32_t *)load_entry,
- *((uint32_t *)load_entry + 1),
- *((uint32_t *)load_entry + 2),
- *((uint32_t *)load_entry + 3));
- /* Fill residual data structure */
- residual_build(res, memsize, (uint32_t)load_base,
- (uint32_t)boot_nb * part_blocsize(boot_part),
- (uint32_t)last_alloc);
- /* Fill bootinfos */
- bootinfos = (void *)(((uint32_t)load_end + (1 << 20) - 1) & ~((1 << 20) - 1));
- if (boot_image != NULL && cmdline == NULL) {
- cmdline = bootinfos + 0x1000;
- *(char *)cmdline = '\0';
- }
- set_check(0);
- prepare_bootinfos(bootinfos, memsize, cmdline, ramdisk, ramdisk_size);
- set_check(1);
- if (part_flags(boot_part) & PART_PREP) {
- vga_prep_init();
- }
- /* Format NVRAM */
- NVRAM_format(nvram);
- /* Setup MMU and boot the loaded image */
- DPRINTF("\nSet up MMU context\n");
- /* Map all memory with transparent mapping */
- BAT_setup(0, 0x00000000, 0x00000000, memsize, 1, 0, 2);
- /* Open IO ports */
- BAT_setup(1, isa_io_base, isa_io_base, 0x00800000, 1, 1, 2);
-#if 0
- /* Open the frame-buffer area */
- BAT_setup(2, vga_fb_phys_addr, vga_fb_phys_addr, 0x00200000, 1, 1, 2);
-#else
- if (pci_main != NULL) {
- uint32_t mem_start, mem_size;
- pci_get_mem_range(pci_main, &mem_start, &mem_size);
- BAT_setup(2, mem_start, mem_start, mem_size, 1, 1, 2);
- }
-#endif
- /* Enable MMU */
- MMU_on();
- usleep(500);
- dprintf("Boot: %08x %08x %08x %08x\n", *(uint32_t *)load_base,
- *(uint32_t *)(load_base + 4), *(uint32_t *)(load_base + 8),
- *(uint32_t *)(load_base + 12));
- dprintf("Bootinfos at : %p\n", bootinfos);
- printf("\nNow boot it... (%p)\n\n", malloc(0));
- usleep(500);
- {
- register uint32_t r1 __asm__ ("r1");
- printf("stack: %0x malloc_base: %p 0x05800000 0x06000000\n",
- r1, malloc(0));
- }
-
- if (part_flags(boot_part) & PART_PREP) {
- printf("PREP boot... %p %p\n", load_entry, load_base);
- /* Hack for Linux to boot without OpenFirmware */
- put_be32(load_base, 0xdeadc0de);
- }
- transfer_handler(res /* residual data */,
- load_base /* load address */,
-#ifdef USE_OPENFIRMWARE
- &OF_entry /* OF entry point */,
-#else
- NULL,
-#endif
- bootinfos /* bootinfos for Linux */,
- cmdline /* command line for Linux */,
- NULL /* unused for now */,
- load_entry /* start address */,
-#if 0
- mem_align(0x00100000) /* Stack base */
-#else
- (void *)0x05800000
-#endif
- );
- /* Should never come here */
-
- return 0;
-}