home *** CD-ROM | disk | FTP | other *** search
- /* $NetBSD$ */
-
- /*
- * Copyright (c) 1994-1996 Mark Brinicombe.
- * Copyright (c) 1994-1996 Brini.
- * All rights reserved.
- *
- * This code is derived from software written for Brini by Mark Brinicombe
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Mark Brinicombe.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * RiscBSD kernel project
- *
- * bsdbooter.c
- *
- * RiscBSD boot loader
- *
- * Created : 12/09/94
- * Last updated : 12/07/96
- *
- * Based on kate/boot/boot.c
- *
- * $Id$
- */
-
- /* Include standard header files */
-
- #include <stdarg.h>
-
- /* Include local headers */
-
- #include "katelib.h"
- #include "swiv.h"
- #include "swis.h"
- #include "arm.h"
- #include "stand.h"
-
- #include "bootconfig.h"
-
- /*
- * Declare global variables
- */
-
- # define VERSION "2.80"
-
- # define USE_MODULEAREA
-
- # define KERNAREA 512
- # define KERNBASE 0xf0000000
-
- # define TABLEAREA 513
- # define LOADAREA 514
-
- # define SCRATCHSIZE 0xc000
-
-
- # define OS_DynamicArea 0x66
- # define OS_Memory 0x68
- # define OS_MMUControl 0x6b
-
- # define FASTBOOT_FILENAME "<BtRiscBSD$Dir>.booter.fastboot"
-
- /*
- * Declare external variables
- */
-
- extern char *__cli;
-
- /*
- * Local vars. Some of these have to be global because they are used after
- * the processor has been switches to SVC mode local variables would be
- * lost as they would be on the USR mode stack.
- */
-
- BootConfig bootconfig;
- int in[3], out[3];
- char kernelname[1024];
- unsigned char *buffer;
- static aout_t aout;
- unsigned int stringtablesize;
- unsigned int kernelsize;
- unsigned int logical;
- unsigned int physical;
- unsigned int filesize;
- unsigned int copysize;
- unsigned int ptr;
- /*
- * Local function prototypes
- */
-
- void fatal(struct Error *error);
- unsigned char *locate_memory_blocks(void);
- void _bsdboot(BootConfig *bootconfig, unsigned int address);
-
- /* Now for the main code */
-
- extern int main (int, char **);
-
- void __exit(int);
-
- void _main(void)
- {
- __exit (main (0, (char **)0)); /* ... ignition */
-
- /* not reached */
- }
-
- /* The main booter code */
-
- int main(int argc, char *argv[])
- {
- char *cliptr;
- int loop;
- int filehandle;
- unsigned char *arrangementtable;
- struct Error *error;
-
- /* Analyse the command line */
-
- cliptr = __cli;
-
- /* Skip the command name */
-
- while (*cliptr != ' ' && *cliptr != 0)
- ++cliptr;
-
- /* Skip any spaces */
-
- while (*cliptr == ' ')
- ++cliptr;
-
- /* Check for another parameter */
-
- if (*cliptr != 0)
- {
- for (loop = 0; *cliptr != ' ' && *cliptr != 0; ++loop,++cliptr)
- {
- kernelname[loop] = *cliptr;
- }
- kernelname[loop] = 0;
- }
- else
- strcpy(kernelname, "netbsd");
-
- strcpy(bootconfig.kernelname, kernelname);
-
- /* Write the command line used to a fastboot file. Execing or Obeying
- * this file will boot RiscBSD. This can be used during the RiscOS bootup
- * to enable a fast boot.
- */
-
- /*
- * Open the autoboot file. Just skip if file cannot be opened.
- */
-
- if (strstr(__cli, "nofb") == 0)
- {
- error = swix(OS_Find, IN(R0|R1)|OUT(R0), 0x80, FASTBOOT_FILENAME, &filehandle);
- if (error == NULL && filehandle != 0)
- {
- swi(OS_GBPB, IN(R0|R1|R2|R3|R4), 2, filehandle, __cli,
- strlen(__cli), 0);
- swi(OS_GBPB, IN(R0|R1|R2|R3|R4), 2, filehandle, "\n", 1, 0);
-
- /* Close the file */
-
- swi(OS_Find, IN(R0|R1), 0, filehandle);
-
- swi(OS_File, IN(R0|R1|R2), 18, FASTBOOT_FILENAME, 0xfeb);
- }
- else
- {
- printf("Warning: Cannot write fastboot file %s\n", FASTBOOT_FILENAME);
- }
- }
-
- /* Set the screen mode ... */
-
- /* I know this is messy. It is currently just a hack to try things out
- * Why didn't Acorn add a SWI call to interpret the mode string and return
- * a mode specifer ?
- */
-
- /* Also this is temporary as eventually the console driver will set the VIDC
- * up as required.
- * It sort of expects the screenmode= options to be at the end of the string.
- */
-
- {
- char *modeptr;
- int modespec[6];
-
- modeptr = strstr(__cli, "screenmode=");
- if (modeptr)
- {
- modeptr += 11;
- modespec[0] = 0x00000001;
- modespec[1] = 0x00000000;
- modespec[2] = 0x00000000;
- modespec[3] = 0x00000003;
- modespec[4] = 0x00000000;
- modespec[5] = -1;
-
- while (*modeptr)
- {
- switch (*modeptr)
- {
- case 'X':
- case 'x':
- ++modeptr;
- while (*modeptr >= '0' && *modeptr <= '9')
- {
- modespec[1] = (modespec[1] * 10) + (*modeptr - '0');
- ++modeptr;
- }
- break;
-
- case 'Y':
- case 'y':
- ++modeptr;
- while (*modeptr >= '0' && *modeptr <= '9')
- {
- modespec[2] = (modespec[2] * 10) + (*modeptr - '0');
- ++modeptr;
- }
- break;
- /*
- case 'C':
- case 'c':
- case 'G':
- case 'g':
- ++modeptr;
- while (*modeptr >= '0' && *modeptr <= '9')
- {
- modespec[3] = (modespec[3] * 10) + (*modeptr - '0');
- ++modeptr;
- }
- break;
- */
- case 'F':
- case 'f':
- ++modeptr;
- while (*modeptr >= '0' && *modeptr <= '9')
- {
- modespec[4] = (modespec[4] * 10) + (*modeptr - '0');
- ++modeptr;
- }
- break;
-
- default:
- ++modeptr;
- break;
- }
- }
- if (modespec[4] == 0) modespec[4] = -1;
- /* printf("x=%d y=%d c=%d f=%d\n", modespec[1], modespec[2],
- modespec[3], modespec[4]);*/
- fatal(swix(Wimp_SetMode, IN(R0), &modespec));
- bootconfig.framerate = modespec[4];
- }
- else
- bootconfig.framerate = 0;
- }
-
- /* Announcement time .. */
-
- if (strstr(__cli, "verbose") != 0)
- printf("RiscBSD BootLoader " VERSION " " __DATE__ "\n");
-
- /* A bit of info */
-
- if (strstr(__cli, "verbose") != 0)
- printf("Kernel: %s\n\r", kernelname);
-
- /* Get the machine id */
-
- fatal(swix(OS_ReadSysInfo, IN(R0)|OUT(R3), 2, &bootconfig.machine_id));
-
- bootconfig.magic = BOOTCONFIG_MAGIC;
-
- /* Get the display variables. Failure on any of these will abort the boot */
-
- in[0] = 149;
- in[1] = 150;
- in[2] = -1;
-
- fatal(swix(OS_ReadVduVariables, IN(R0|R1), &in, &out));
-
- bootconfig.display_start = out[0];
- bootconfig.display_size = out[1];
-
- fatal(swix(OS_ReadModeVariable, IN(R0|R1) | OUT(R2), -1, 9,
- &bootconfig.bitsperpixel));
- fatal(swix(OS_ReadModeVariable, IN(R0|R1) | OUT(R2), -1, 11,
- &bootconfig.width));
- fatal(swix(OS_ReadModeVariable, IN(R0|R1) | OUT(R2), -1, 12,
- &bootconfig.height));
-
- {
- int pageblock[3];
-
- pageblock[1] = bootconfig.display_start;
- fatal(swix(OS_Memory, IN(R0|R1|R2) | OUT(R1), 0x2200,
- pageblock, 1, pageblock));
- bootconfig.vdram_phys = pageblock[2];
- }
-
- /* Will the kernel support this mode ? */
-
- if (bootconfig.bitsperpixel != 3)
- {
- printf("Error: Current kernels only support 8 bpp for booting.\n");
- return(0);
- }
-
- /* Will the kernel support this mode ? */
-
- if (bootconfig.bitsperpixel > 3)
- {
- printf("Error: Only 1, 2, 4 or 8 bpp modes are currently supported\n");
- return(0);
- }
-
- /* Get the arrangement table for the memory */
-
- arrangementtable = locate_memory_blocks();
-
- /*
- * Ok we support a.out files. This means that we need to
- * identify the type.
- */
-
- /* Get the size of the file */
-
- filesize = 0;
- fatal(swix(OS_File, IN(R0|R1)|OUT(R4), 5, kernelname, &filesize));
-
- /* Verbose info to the user. This is mainly debugging */
-
- if (strstr(__cli, "verbose") != 0)
- printf("filesize = %08x\n", filesize);
-
- if (filesize == 0) {
- printf("Error: Kernel image too small\n");
- return(0);
- }
-
- # ifdef USE_MODULEAREA
-
- /* Allocate memory in module area to hold the data we are loading */
-
- fatal(swix(OS_Module, IN(R0|R3)|OUT(R2), 6, filesize, &buffer));
-
- # else
-
- /* Allocate memory to hold the data we are loading */
-
- swix(OS_DynamicArea, IN(R0|R1), 1, LOADAREA);
-
- fatal(swix(OS_DynamicArea, IN(R0|R1|R2|R3|R4|R5|R6|R7|R8)|OUT(R3), 0,
- LOADAREA, filesize, -1, 0x80, filesize, 0, 0, "Kate Data", &buffer));
-
- # endif
-
- /*
- * Open the file.
- */
-
- swi(OS_Find, IN(R0|R1)|OUT(R0), 0x40, kernelname, &filehandle);
- if (filehandle == 0)
- {
- printf("Error: Cannot read kernel file %s\n", kernelname);
- return(0);
- }
-
- /* Load the file into memory */
-
- swi(OS_GBPB, IN(R0|R1|R2|R3|R4), 3, filehandle, buffer, filesize, 0);
-
- /* Close the file */
-
- fatal(swix(OS_Find, IN(R0|R1), 0, filehandle));
-
- /* Take a copy of the possible a.out header */
-
- aout = *((aout_t *)buffer);
-
- /* Do we have an a.out file ? */
-
- switch(aout.a_magic & MAGICMASK) {
- case NMAGIC:
- if (strstr(__cli, "verbose") != 0)
- printf("Kernel binary is NMAGIC a.out format\n");
- aout.a_syms = 0;
- stringtablesize = 0;
- break;
- case OMAGIC:
- if (strstr(__cli, "verbose") != 0)
- printf("Kernel binary is OMAGIC a.out format\n");
- aout.a_syms = 0;
- stringtablesize = 0;
- break;
- case ZMAGIC:
- if (strstr(__cli, "verbose") != 0)
- printf("Kernel binary is ZMAGIC a.out format\n");
- stringtablesize = filesize - (unsigned int)(aout.a_text +
- aout.a_data + aout.a_syms);
- if (aout.a_entry < KERNBASE || aout.a_entry > KERNBASE + 0x00100000) {
- printf("Error: Kernel entry point out of range\n");
- return(0);
- }
- break;
- default:
- if (strstr(__cli, "verbose") != 0)
- printf("Kernel binary is unrecognised, guessing it is AIF format\n");
- aout.a_text = filesize;
- aout.a_data = 0;
- aout.a_bss = 0;
- aout.a_syms = 0;
- stringtablesize = 0;
- break;
- }
-
- kernelsize = (unsigned int)(aout.a_text + aout.a_data + aout.a_bss);
-
- /* Add symbol table size if required. */
-
- if (strstr(__cli, "symtab") != 0) {
- kernelsize += (unsigned int)aout.a_syms + stringtablesize;
- } else {
- aout.a_syms = 0;
- stringtablesize = 0;
- }
-
- if (strstr(__cli, "verbose") != 0)
- {
- printf("a_text = %08x\n", aout.a_text);
- printf("a_data = %08x\n", aout.a_data);
- printf("a_bss = %08x\n", aout.a_bss);
- printf("a_syms = %08x\n", aout.a_syms);
- printf("snames = %08x\n", stringtablesize);
- }
-
- /* Give ourselves 16K of spare space and round off to a page */
-
- kernelsize = (kernelsize + 0x4000) & ~(bootconfig.pagesize-1);
-
- /* Set the virtual address of the kernel in the bootconfig structure */
-
- bootconfig.kernvirtualbase = KERNBASE;
- bootconfig.kernsize = kernelsize;
- bootconfig.argvirtualbase = bootconfig.kernvirtualbase
- + bootconfig.kernsize;
- bootconfig.argsize = bootconfig.pagesize;
- bootconfig.scratchvirtualbase = bootconfig.argvirtualbase
- + bootconfig.argsize;
- bootconfig.scratchsize = SCRATCHSIZE;
-
- kernelsize += bootconfig.argsize;
-
- kernelsize += bootconfig.scratchsize;
-
- /* Verbose info to the user. This is mainly debugging */
-
- if (strstr(__cli, "verbose") != 0)
- {
- printf("filesize = %08x\n", filesize);
- printf("bootconfig.kernvirtualbase = %08x\n",
- bootconfig.kernvirtualbase);
- printf("bootconfig.kernsize = %08x\n", bootconfig.kernsize);
- printf("bootconfig.argvirtualbase = %08x\n",
- bootconfig.argvirtualbase);
- printf("bootconfig.argsize = %08x\n", bootconfig.argsize);
- printf("bootconfig.scratchvirtualbase = %08x\n",
- bootconfig.scratchvirtualbase);
- printf("bootconfig.scratchsize = %08x\n", bootconfig.scratchsize);
- printf("kernelsize = %08x\n", kernelsize);
- printf("display_start = %08x\n", bootconfig.display_start);
- printf("display_size = %08x\n", bootconfig.display_size);
- printf("physical dstart = %08x\n", bootconfig.vdram_phys);
- }
-
- /* This is redundant at the moment */
-
- swix(OS_DynamicArea, IN(R0|R1), 1, KERNAREA);
-
- fatal(swix(OS_DynamicArea, IN(R0|R1|R2|R3|R4|R5|R6|R7|R8), 0,
- KERNAREA, 0, KERNBASE, 0x80, 0x1000, 0, 0, "Kate Kernel"));
-
- /* Shutdown RiscOS cleanly ... */
-
- /* Close all open files and shutdown filing systems */
-
- if (strstr(__cli, "noboot") == 0)
- {
- swix(OS_FSControl, IN(R0), 23);
-
- /* Issue a pre-reset service call to reset the podules */
-
- swix(OS_ServiceCall, IN(R1), 0x45);
-
- /* Kill the etherH module to avoid locks up on reboot */
-
- /* swix(OS_Module, IN(R0|R1), 4, "EtherH");*/
- }
-
- /* More user information describing the memory found */
-
- if (strstr(__cli, "verbose") != 0)
- {
- printf("DRAM bank 0a = %08x %08x\n", bootconfig.dram[0].address,
- bootconfig.dram[0].pages * bootconfig.pagesize);
- printf("DRAM bank 0b = %08x %08x\n", bootconfig.dram[1].address,
- bootconfig.dram[1].pages * bootconfig.pagesize);
- printf("DRAM bank 1a = %08x %08x\n", bootconfig.dram[2].address,
- bootconfig.dram[2].pages * bootconfig.pagesize);
- printf("DRAM bank 1b = %08x %08x\n", bootconfig.dram[3].address,
- bootconfig.dram[3].pages * bootconfig.pagesize);
- printf("VRAM bank 0 = %08x %08x\n", bootconfig.vram[0].address,
- bootconfig.vram[0].pages * bootconfig.pagesize);
- }
-
- /* Jump to SVC26 mode - remember we have no local vars now ! */
-
- EnterOS();
-
- /* Find the number of the upper most bank of DRAM available */
-
- loop = 3;
- while (bootconfig.dram[loop].address == 0)
- --loop;
-
- /* Allocate the physical addresses for the kernel in this bank */
-
- physical = bootconfig.dram[loop].address - kernelsize
- + bootconfig.dram[loop].pages * bootconfig.pagesize;
- bootconfig.kernphysicalbase = physical;
- bootconfig.argphysicalbase = bootconfig.kernphysicalbase
- + bootconfig.kernsize;
- bootconfig.scratchphysicalbase = bootconfig.argphysicalbase
- + bootconfig.argsize;
-
- /* Yet more debugging info */
-
- if (strstr(__cli, "verbose") != 0)
- {
- printf("buffer = %08x\n", buffer);
- printf("physical = %08x\n", physical);
- printf("bootconfig.kernphysicalbase = %08x\n",
- bootconfig.kernphysicalbase);
- printf("bootconfig.argphysicalbase = %08x\n",
- bootconfig.argphysicalbase);
- printf("bootconfig.scratchphysicalbase = %08x\n",
- bootconfig.scratchphysicalbase);
- }
-
- /*
- * Ok just check to see if anything is mapped where we are about to map
- * the kernel.
- */
-
- /*
- for (logical = KERNBASE; logical < KERNBASE + kernelsize;
- logical += bootconfig.pagesize)
- {
- if (ReadWord(0x02c00000 + (logical >> 10) & 0xfffffffc) != 0)
- {
- printf("Error: Memory required for RiscBSD boot not available\n\r");
- return(0);
- }
- }
- */
- /* Get out clause */
-
- if (strstr(__cli, "noboot") != 0)
- {
- ExitOS();
- #ifdef USE_MODULEAREA
-
- /* Free memory in module area to hold the data we were loading */
-
- fatal(swix(OS_Module, IN(R0|R2), 7, buffer));
-
- #endif
- return(0);
- }
-
- /*
- * Hook the physical pages to the required virtual address directly by
- * writing into RiscOS's page tables. This should be done via a
- * dynamic area handler but I cannot get it to work as documented.
- */
-
- for (logical = KERNBASE; logical < KERNBASE + kernelsize;
- logical += bootconfig.pagesize)
- {
- WriteWord(0x02c00000 + (logical >> 10) & 0xfffffffc,
- 0x00000ffe | (physical & 0xfffff000));
- physical += bootconfig.pagesize;
- }
-
- /* Map the IO up high so we can get at it */
-
- WriteWord(0x02c0c000 + (0xf6000000 >> 18) & 0xfffffffc,
- 0x00000412 | (0x03200000 & 0xfffff000));
- WriteWord(0x02c0c000 + (0xf6100000 >> 18) & 0xfffffffc,
- 0x00000412 | (0x03400000 & 0xfffff000));
-
- memset((char *)bootconfig.display_start, 0xcc, 0x4000);
-
- /* Disable IRQ and FIQ interrupts */
-
- SetCPSR(I32_bit | F32_bit, I32_bit | F32_bit);
-
- memset((char *)bootconfig.display_start + 0x4000, 0x55, 0x4000);
-
- memcpy((char *)bootconfig.argvirtualbase, __cli, bootconfig.argsize);
-
- memset((char *)bootconfig.display_start + 0x8000, 0x80, 0x4000);
-
- memset((char *)bootconfig.argvirtualbase, SCRATCHSIZE, 0);
-
- memset((char *)bootconfig.display_start + 0xC000, 0xbb, 0x4000);
-
- /* Locate the start of the text area */
-
- switch (aout.a_magic & MAGICMASK) {
- case OMAGIC:
- case NMAGIC:
- buffer += sizeof(aout_t);
- break;
- case ZMAGIC:
- default:
- break;
- }
-
- switch (aout.a_magic & MAGICMASK) {
- case OMAGIC:
- case NMAGIC:
- case ZMAGIC:
- if (aout.a_syms == 0)
- ((aout_t *)buffer)->a_syms = 0;
- break;
- default:
- break;
- }
-
- memcpy((char *)bootconfig.kernvirtualbase, buffer, (int)aout.a_text);
-
- memset((char *)(bootconfig.display_start + 0x10000), 0xee, 0x4000);
-
- memcpy((char *)(bootconfig.kernvirtualbase + aout.a_text),
- (buffer + aout.a_text), (int)aout.a_data);
-
- memset((char *)(bootconfig.display_start + 0x14000), 0x66, 0x4000);
-
- if (aout.a_syms != 0) {
- ptr = bootconfig.kernvirtualbase + (u_int)(aout.a_text
- + aout.a_data + aout.a_bss);
- *((int *)ptr) = (int)aout.a_syms;
- ptr += sizeof(int);
- memcpy((char *)ptr, (buffer + aout.a_text
- + aout.a_data), (int)aout.a_syms);
- ptr += (int)aout.a_syms;
- memcpy((char *)ptr, (buffer + aout.a_text
- + aout.a_data + aout.a_syms), stringtablesize);
-
- }
-
- memset((char *)bootconfig.display_start + 0x18000, 0xaa, 0x4000);
-
- /* Real late debugging get out clause */
-
- if (strstr(__cli, "nearboot") != 0)
- {
- SetCPSR(I32_bit | F32_bit, 0);
- ExitOS();
- return(0);
- }
-
- /* Punch into SVC32 mode */
-
- memset((char *)bootconfig.display_start + 0x1C000, 0xff, 0x4000);
-
- SVC32();
-
- /* Point of no return */
-
- switch (aout.a_magic & MAGICMASK) {
- case OMAGIC:
- case NMAGIC:
- case ZMAGIC:
- _bsdboot(&bootconfig, (unsigned int)aout.a_entry);
- break;
- default:
- _bsdboot(&bootconfig, KERNBASE);
- break;
- }
-
- return(0);
- }
-
-
- /* Report an error */
-
- void fatal(struct Error *error)
- {
- if (error)
- swi(OS_GenerateError, IN(R0), error);
- }
-
-
- /* Locate all the blocks of memory in the system */
-
- unsigned char *locate_memory_blocks(void)
- {
- int loop;
- int page;
- int currentpage;
- int currentpages;
- int currentaddr;
- unsigned char *table;
- unsigned int pagesize;
- unsigned int tablesize;
- int dramblocks = 0;
- int vramblocks = 0;
-
- /* Get table size and page size */
-
- fatal(swix(OS_Memory, IN(R0)|OUT(R1|R2), 6, &tablesize, &pagesize));
-
- /* Allocate memory for table */
-
- /*# ifdef USE_MODULEAREA*/
-
- fatal(swix(OS_Module, IN(R0|R3)|OUT(R2), 6, tablesize, &table));
-
- /*# else*/
-
- /* Allocate memory to hold the data we are loading */
-
- /* swix(OS_DynamicArea, IN(R0|R1), 1, TABLEAREA);
-
- fatal(swix(OS_DynamicArea, IN(R0|R1|R2|R3|R4|R5|R6|R7|R8)|OUT(R3), 0,
- TABLEAREA, tablesize, -1, 0x80, tablesize, 0, 0, "Kate Table", &table));
-
- # endif*/
-
-
- /* read the table */
-
- fatal(swix(OS_Memory, IN(R0|R1), 7, table));
-
- /* Loop round locating all the valid blocks of memory */
-
- currentpage = -1;
-
- for (loop = 0; loop < tablesize * 2; ++loop)
- {
- page = table[loop / 2];
- if (loop % 2)
- page = page >> 4;
-
- page = page & 0x07;
-
- if (page != currentpage)
- {
- switch (currentpage)
- {
- case 1:
- bootconfig.dram[dramblocks].address = currentaddr * pagesize;
- bootconfig.dram[dramblocks].pages = currentpages;
- ++dramblocks;
- break;
-
- case 2:
- bootconfig.vram[vramblocks].address = currentaddr * pagesize;
- bootconfig.vram[vramblocks].pages = currentpages;
- ++vramblocks;
- break;
-
- default :
- break;
- }
-
- currentpage = page;
- currentaddr = loop;
- currentpages = 0;
- }
- ++currentpages;
- }
-
- /* Get the number of dram and vram pages */
-
- fatal(swix(OS_Memory, IN(R0)|OUT(R1), 0x00000108, &bootconfig.drampages));
- fatal(swix(OS_Memory, IN(R0)|OUT(R1), 0x00000208, &bootconfig.vrampages));
-
- /* Fill in more bootconfig parameters */
-
- bootconfig.pagesize = pagesize;
-
- bootconfig.dramblocks = dramblocks;
- bootconfig.vramblocks = vramblocks;
-
- return(table);
- }
-
-
- void putchar(int c)
- {
- if (c == '\n')
- swi(OS_WriteC, IN(R0), '\r');
-
- swi(OS_WriteC, IN(R0), c);
- }
-
- /* End of bsdbooter.c */
-