From 47e3cefe5babd1624543beb5a59f1d2fb63ddf21 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 4 Oct 2006 08:10:01 +0000 Subject: [PATCH] - Create a slab that contains the last vestage of our life as the boot program. - Include a font containing some characters we can use with boot video. - Copy in a description of the boot framebuffer. - Add a small ad-hoc number writing function. - Display our progress building the initial page table. - We don't necessarily have space in the boot-time page table so just kill off boot-time paging. - Pass ntoskrnl the address of the boot slab. It contains the boot font, a description of the boot video device and all active page table entries. - Next, well be able to use this in early ntoskrnl space to display our progress etc. Since we're using phyiscal addresses to write to the boot framebuffer, the page table needn't include it. This simplifies things compared to linux, but it's expensive. svn path=/branches/powerpc/; revision=24390 --- .../boot/freeldr/freeldr/arch/powerpc/boot.s | 5 + .../freeldr/freeldr/arch/powerpc/compat.h | 101 ++++++++++++++++++ .../boot/freeldr/freeldr/arch/powerpc/mach.c | 30 ++++-- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 96 +++++++++++++++-- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 4 +- .../boot/freeldr/freeldr/arch/powerpc/mmu.h | 2 +- reactos/include/reactos/ppcboot.h | 2 + 7 files changed, 218 insertions(+), 22 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s index 30c1f1c3e18..c522936d0a7 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s @@ -1,3 +1,8 @@ .extern PpcInit _start: b PpcInit + + .globl _bss + .section ".bss" +_bss: + .long 0 diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h index 66797a6929d..031710e7096 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h @@ -103,6 +103,107 @@ void btext_drawhex(unsigned long v); void *ioremap(__u32 phys, __u32 size); void iounmap(void *logical); +font_char BootDigits[16] = { + " XXXXX " + "X X " + "X x X " + "X X X " + "X X " + " XXXXX " + " ", + " XX " + " XXX " + " XX " + " XX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XX " + " XX " + " XX " + " XXXXXX " + " ", + " XXXX " + " X X " + " XX " + " X " + " X X " + " XXXX " + " ", + " X X " + " X X " + " XXXXXX " + " X " + " X " + " X " + " ", + " XXXXXX " + " X " + " XXXXX " + " X " + " X " + " XXXXX " + " ", + " XXXXX " + " X " + " XXXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXXXX " + " XX " + " XX " + " XXXXX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXX " + " X X " + " XXXXXX " + " X X " + " X X " + " X X " + " ", + " XXXXX " + " X X " + " XXXXX " + " X X " + " X X " + " XXXXX " + " ", + " XXXX " + " X X " + " X " + " X " + " X X " + " XXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " XXXXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " X " + " " +}; + __u32 GetPVR(); #endif/*_FREELDR_ARCH_COMPAT_H*/ diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 39650347876..6e5ac5c9d7f 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -28,7 +28,7 @@ extern PCHAR GetFreeLoaderVersionString(); extern ULONG CacheSizeLimit; of_proxy ofproxy; void *PageDirectoryStart, *PageDirectoryEnd; -static int chosen_package, stdin_handle, part_handle = -1; +static int chosen_package, stdin_handle, part_handle = -1, kernel_mem = 0; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; @@ -340,10 +340,20 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, (int)BiosMemoryMap[slots].BaseAddress, (int)BiosMemoryMap[slots].Length); - if( BiosMemoryMap[slots].Length && + /* Hack for pearpc */ + if( kernel_mem ) { + BiosMemoryMap[slots].Length = kernel_mem * 1024; ofw_claim((int)BiosMemoryMap[slots].BaseAddress, (int)BiosMemoryMap[slots].Length, - 0x1000) ) { + 0x1000); + total += BiosMemoryMap[slots].Length; + slots++; + break; + /* Normal way */ + } else if( BiosMemoryMap[slots].Length && + ofw_claim((int)BiosMemoryMap[slots].BaseAddress, + (int)BiosMemoryMap[slots].Length, + 0x1000) ) { total += BiosMemoryMap[slots].Length; slots++; } @@ -555,11 +565,11 @@ void PpcInit( of_proxy the_ofproxy ) { len = ofw_getprop(chosen_package, "bootargs", CmdLine, sizeof(CmdLine)); - printf("bootargs: len %d\n", len); - if( len < 0 ) len = 0; CmdLine[len] = 0; + printf("bootargs: len %d [%s]\n", len, CmdLine); + BootMain( CmdLine ); } @@ -572,15 +582,19 @@ void MachInit(const char *CmdLine) { printf( "Determining boot device: [%s]\n", CmdLine ); - printf( "Boot Args: %s\n", CmdLine ); sep = NULL; for( i = 0; i < strlen(CmdLine); i++ ) { if( strncmp(CmdLine + i, "boot=", 5) == 0) { strcpy(BootPart, CmdLine + i + 5); - sep = strchr(BootPart, ' '); + sep = strchr(BootPart, ','); if( sep ) *sep = 0; - break; + while(CmdLine[i] && CmdLine[i]!=',') i++; + } + if( strncmp(CmdLine + i, "mem=", 4) == 0) { + kernel_mem = atoi(CmdLine+i+4); + printf("Allocate %dk kernel memory\n", kernel_mem); + while(CmdLine[i] && CmdLine[i]!=',') i++; } } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 6ad18c5e5d7..a423027d227 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -20,12 +20,15 @@ #include #include +#include "ppcboot.h" #include "mmu.h" +#include "compat.h" #define NDEBUG #include static PVOID KernelMemory = 0; +extern boot_infos_t BootInfo; /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ #define PFN_SHIFT 12 @@ -107,26 +110,97 @@ ULONG_PTR KernelEntry; typedef void (*KernelEntryFn)( void * ); +VOID +DrawDigit(boot_infos_t *BootInfo, ULONG Digit, int x, int y) +{ + int i,j,k; + + for( i = 0; i < 7; i++ ) { + for( j = 0; j < 8; j++ ) { + for( k = 0; k < BootInfo->dispDeviceDepth/8; k++ ) { + SetPhysByte(((ULONG_PTR)BootInfo->dispDeviceBase)+ + k + + (((j+x) * (BootInfo->dispDeviceDepth/8)) + + ((i+y) * (BootInfo->dispDeviceRowBytes))), + BootInfo->dispFont[Digit][i*8+j] == ' ' ? 0 : 255); + } + } + } +} + +VOID +DrawNumber(boot_infos_t *BootInfo, ULONG Number, int x, int y) +{ + int i; + + for( i = 0; i < 8; i++, Number<<=4 ) { + DrawDigit(BootInfo,(Number>>28)&0xf,x+(i*8),y); + } +} + VOID NTAPI FrLdrStartup(ULONG Magic) { KernelEntryFn KernelEntryAddress = (KernelEntryFn)(KernelEntry + KernelBase); - ULONG_PTR PhysAddr, i; - - for( i = 0; i < KernelMemorySize; i+=1<> PFN_SHIFT; + UINT NeededMemory = + (2 * sizeof(ULONG_PTR) * (NeededPTE + NeededPTE / 512)) + + sizeof(BootInfo) + sizeof(BootDigits); + UINT NeededPages = ROUND_UP(NeededMemory,(1<dispFont = (font_char *)&LocalBootInfo[1]; + + TranslationMap[0] = (ULONG_PTR)FrLdrStartup; + for( i = 1; i < NeededPages; i++ ) { - PhysAddr = PpcVirt2phys((ULONG)KernelMemory + i,0); - - if( !InsertPageEntry(KernelBase + i,PhysAddr) ) - { - printf("Foo: couldn't find a page slot for %x\n", i); - while(1); - } + TranslationMap[i*2] = NeededMemory+(i<>PFN_SHIFT; j++ ) + { + TranslationMap[(i+j)*2] = ((UINT)(KernelMemory+(i<>10)); + } + + /* Tell them we're booting */ + DrawNumber(LocalBootInfo,0x1cabba9e,10,120); + DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,120); + + KernelEntryAddress( (void*)LocalBootInfo ); while(1); } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index 84a310e8470..39f7b72568d 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -293,7 +293,7 @@ int PpcVirt2phys( int virt, int inst ) { } /* Add a new page table entry for the indicated mapping */ -BOOLEAN InsertPageEntry( int virt, int phys ) { +BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { int i, ptehi, ptelo; int sdr1 = GetSDR1(); int sr = GetSR( (virt >> 28) & 0xf ); @@ -307,7 +307,7 @@ BOOLEAN InsertPageEntry( int virt, int phys ) { for( i = 0; i < 8; i++ ) { ptehi = GetPhys( ptegaddr + (i * 8) ); - if( ptehi & 0x80000000 ) continue; + if( (slot != i) && (ptehi & 0x80000000) ) continue; ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f); ptelo = phys & ~0xfff; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h index 2baed2a5f43..99d8bb2e3ac 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h @@ -14,6 +14,6 @@ int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); /* translate address */ int PpcVirt2phys( int virt, int inst ); -BOOLEAN InsertPageEntry( int virt, int phys ); +BOOLEAN InsertPageEntry( int virt, int phys, int slot ); #endif/*FREELDR_MMU_H*/ diff --git a/reactos/include/reactos/ppcboot.h b/reactos/include/reactos/ppcboot.h index 96e7baa2af2..460af14eba9 100644 --- a/reactos/include/reactos/ppcboot.h +++ b/reactos/include/reactos/ppcboot.h @@ -1,11 +1,13 @@ #ifndef REACTOS_PPCBOOT_H #define REACTOS_PPCBOOT_H +typedef char font_char[57]; typedef struct _boot_infos_t { int dispDeviceRect[4]; int dispDeviceRowBytes; int dispDeviceDepth; void *dispDeviceBase; + font_char *dispFont; } boot_infos_t; #endif/*REACTOS_PPCBOOT_H*/