From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- roms/openbios/arch/ppc/mol/main.c | 370 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 roms/openbios/arch/ppc/mol/main.c (limited to 'roms/openbios/arch/ppc/mol/main.c') diff --git a/roms/openbios/arch/ppc/mol/main.c b/roms/openbios/arch/ppc/mol/main.c new file mode 100644 index 000000000..f6ed934d0 --- /dev/null +++ b/roms/openbios/arch/ppc/mol/main.c @@ -0,0 +1,370 @@ +/* + * Creation Date: <2002/10/02 22:24:24 samuel> + * Time-stamp: <2004/03/27 01:57:55 samuel> + * + * + * + * + * + * Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + + +#include "config.h" +#include "libopenbios/bindings.h" +#include "libopenbios/elfload.h" +#include "arch/common/nvram.h" +#include "libc/diskio.h" +#include "libc/vsprintf.h" +#include "mol/mol.h" +#include "libopenbios/ofmem.h" +#include "osi_calls.h" +#include "ablk_sh.h" +#include "boothelper_sh.h" + + +static void patch_newworld_rom( char *start, size_t size ); +static void newworld_timer_hack( char *start, size_t size ); + +static void +transfer_control_to_elf( unsigned long entry ) +{ + extern void call_elf( unsigned long entry ); + printk("Starting ELF boot loader\n"); + call_elf( entry ); + + fatal_error("call_elf returned unexpectedly\n"); +} + +static int +load_elf_rom( unsigned long *entry, int fd ) +{ + int i, lszz_offs, elf_offs; + char buf[128], *addr; + Elf_ehdr ehdr; + Elf_phdr *phdr; + size_t s; + + printk("Loading '%s' from '%s'\n", get_file_path(fd), + get_volume_name(fd) ); + + /* the ELF-image (usually) starts at offset 0x4000 */ + if( (elf_offs=find_elf(fd)) < 0 ) { + printk("----> %s is not an ELF image\n", buf ); + exit(1); + } + if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) + fatal_error("elf_readhdrs failed\n"); + + *entry = ehdr.e_entry; + + /* load segments. Compressed ROM-image assumed to be located immediately + * after the last segment */ + lszz_offs = elf_offs; + for( i=0; i= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { + patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); + newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); + } + flush_icache_range( addr, addr+s ); + + /* printk("ELF ROM-section loaded at %08lX (size %08lX)\n", + (unsigned long)phdr[i].p_vaddr, (unsigned long)phdr[i].p_memsz );*/ + } + free( phdr ); + return lszz_offs; +} + + +/************************************************************************/ +/* newworld ROM loading */ +/************************************************************************/ + +#define ROM_BASE 0x1100000 /* where we decide to put things */ + +/* fix bug present in the 2.4 and the 3.0 Apple ROM */ +static void +patch_newworld_rom( char *start, size_t size ) +{ + int s; + unsigned long mark[] = { 0x7c7d1b78, /* mr r29,r3 */ + 0x7c9c2378, /* mr r28,r4 */ + 0x7cc33378, /* mr r3,r6 */ + 0x7c864214, /* add r4,r6,r8 <------ BUG -- */ + 0x80b10000, /* lwz r5,0(r17) */ + 0x38a500e8 }; /* addi r5,r5,232 */ + + /* Correcting add r4,r6,r8 ----> addi r4,r6,8 */ + for( s=0; s= 0 ) { + entry = (char*)load_newworld_rom( fd ); + close_io( fd ); + } + + /* determine boot volume */ + for( bootunit=-1, type=0; bootunit==-1 && type<3 ; type++ ) { + for( i=0; !OSI_ABlkDiskInfo(0, i, &info) ; i++ ) { + if( type<=1 && !(info.flags & ABLK_BOOT_HINT) ) + continue; + if( type>1 && (info.flags & ABLK_BOOT_HINT) ) + continue; + + for( j=0; !entry && j<32; j++ ) { + snprintf( spec, sizeof(spec), "%s/disk@%x:%d", + path, i, j ); + entry = newworld_load( path, spec, (!type || type==2) ); + } + if( entry ) { + bootunit = i; + break; + } + } + } + + if( entry ) { + OSI_ABlkBlessDisk( 0 /*channel*/, bootunit ); + + update_nvram(); + transfer_control_to_elf( (unsigned long)entry ); + /* won't come here */ + return; + } + + printk("\n--- No bootable disk was found! -----------------------------\n"); + printk("If this is an oldworld machine, try booting from the MacOS\n"); + printk("install CD and install MacOS from within MOL.\n"); + printk("-------------------------------------------------------------\n"); + exit(1); +} + + +/************************************************************************/ +/* yaboot booting */ +/************************************************************************/ + +static void +yaboot_startup( void ) +{ + const char *paths[] = { "pseudo:,ofclient", "pseudo:,yaboot", NULL }; + unsigned long entry; + int i, fd; + + for( i=0; paths[i]; i++ ) { + if( (fd=open_io(paths[i])) == -1 ) + continue; + (void) load_elf_rom( &entry, fd ); + close_io( fd ); + encode_bootpath( paths[i], "" ); + + update_nvram(); + transfer_control_to_elf( entry ); + /* won't come here */ + } + printk("*** Boot failure! No secondary bootloader specified ***\n"); + exit(1); +} + + +/************************************************************************/ +/* entry */ +/************************************************************************/ + +void +boot( void ) +{ + fword("update-chosen"); + if( find_dev("/mol-platform") ) + yaboot_startup(); + else + newworld_startup(); +} -- cgit 1.2.3-korg