/* * Creation Date: <2010/04/02 13:00:00 mcayland> * Time-stamp: <2010/04/02 13:00:00 mcayland> * * * * C implementation of (init-program) word * * Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@siriusit.co.uk) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 * */ #include "config.h" #include "kernel/kernel.h" #include "libopenbios/bindings.h" #include "libopenbios/initprogram.h" /* Because the a.out loader requires platform-specific headers */ #ifdef CONFIG_LOADER_AOUT #include "libopenbios/aout_load.h" #endif #include "libopenbios/bootcode_load.h" #include "libopenbios/bootinfo_load.h" #include "libopenbios/elf_load.h" #include "libopenbios/fcode_load.h" #include "libopenbios/forth_load.h" #include "libopenbios/prep_load.h" #include "libopenbios/xcoff_load.h" void init_program(void) { /* Get the value of load-base and use it to determine the correct loader to use */ ucell addr; feval("load-base"); addr = POP(); #ifdef CONFIG_LOADER_AOUT if (is_aout((struct exec *)cell2pointer(addr))) { aout_init_program(); return; } #endif #ifdef CONFIG_LOADER_BOOTCODE if (is_bootcode((char *)cell2pointer(addr))) { bootcode_init_program(); return; } #endif #ifdef CONFIG_LOADER_BOOTINFO if (is_bootinfo((char *)cell2pointer(addr))) { bootinfo_init_program(); return; } #endif #ifdef CONFIG_LOADER_ELF if (is_elf((Elf_ehdr *)cell2pointer(addr))) { elf_init_program(); return; } #endif #ifdef CONFIG_LOADER_FCODE if (is_fcode((unsigned char *)cell2pointer(addr))) { fcode_init_program(); return; } #endif #ifdef CONFIG_LOADER_FORTH if (is_forth((char *)cell2pointer(addr))) { forth_init_program(); return; } #endif #ifdef CONFIG_LOADER_XCOFF if (is_xcoff((COFF_filehdr_t *)cell2pointer(addr))) { xcoff_init_program(); return; } #endif #ifdef CONFIG_LOADER_PREP if (is_prep((char *)cell2pointer(addr))) { prep_init_program(); return; } #endif } void init_fcode_context(void) { /* Execute FCode payload */ printk("Evaluating FCode...\n"); fword("load-base"); PUSH(1); fword("byte-load"); } void init_forth_context(void) { /* Execute Forth payload */ printk("Evaluating Forth...\n"); fword("load-base"); feval("load-state >ls.file-size @"); fword("eval2"); } void go(void) { /* Switch to the current context */ start_elf(); }