Working out boot video, fixed memory map completely.

svn path=/branches/powerpc/; revision=24332
This commit is contained in:
Art Yerkes
2006-10-01 05:46:59 +00:00
parent 6421038be3
commit 042ade46e9
2 changed files with 257 additions and 50 deletions
@@ -0,0 +1,108 @@
#ifndef _FREELDR_ARCH_COMPAT_H
#define _FREELDR_ARCH_COMPAT_H
#define __init
#define __initdata
#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
#define SPRN_LDSTDB 0x3f4 /* */
#define SPRN_LR 0x008 /* Link Register */
#ifndef SPRN_PIR
#define SPRN_PIR 0x3FF /* Processor Identification Register */
#endif
#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
#define SPRN_PVR 0x11F /* Processor Version Register */
#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
#define SPRN_ASR 0x118 /* Address Space Register */
#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
#ifndef SPRN_SVR
#define SPRN_SVR 0x11E /* System Version Register */
#endif
#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */
/* these bits were defined in inverted endian sense originally, ugh, confusing */
/* Values for PP (assumes Ks=0, Kp=1) */
#define PP_RWXX 0 /* Supervisor read/write, User none */
#define PP_RWRX 1 /* Supervisor read/write, User read */
#define PP_RWRW 2 /* Supervisor read/write, User read/write */
#define PP_RXRX 3 /* Supervisor read, User read */
/* Block size masks */
#define BL_128K 0x000
#define BL_256K 0x001
#define BL_512K 0x003
#define BL_1M 0x007
#define BL_2M 0x00F
#define BL_4M 0x01F
#define BL_8M 0x03F
#define BL_16M 0x07F
#define BL_32M 0x0FF
#define BL_64M 0x1FF
#define BL_128M 0x3FF
#define BL_256M 0x7FF
/* BAT Access Protection */
#define BPP_XX 0x00 /* No access */
#define BPP_RX 0x01 /* Read only */
#define BPP_RW 0x02 /* Read/write */
/* Definitions for 40x embedded chips. */
#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
#define _PAGE_RW 0x040 /* software: Writes permitted */
#define _PAGE_DIRTY 0x080 /* software: dirty page */
#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
#define _PMD_BAD 0x802
#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
#define _PMD_SIZE_4M 0x0c0
#define _PMD_SIZE_16M 0x0e0
#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
#define PVR_VER(pvr)(((pvr) >> 16) & 0xFFFF) /* Version field */
#define KERNELBASE 0x80000000
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;
typedef struct _pci_reg_property {
struct {
int a_hi, a_mid, a_lo;
} addr;
int size_hi, size_lo;
} pci_reg_property;
void btext_drawstring(const char *c);
void btext_drawhex(unsigned long v);
void *ioremap(__u32 phys, __u32 size);
void iounmap(void *logical);
__u32 GetPVR();
#endif/*_FREELDR_ARCH_COMPAT_H*/
+149 -50
View File
@@ -20,19 +20,20 @@
#include "machine.h"
#include "of.h"
#include "mmu.h"
#define TOTAL_HEAP_NEEDED (48 * 1024 * 1024) /* 48 megs */
#include "compat.h"
#include "ppcboot.h"
extern void BootMain( LPSTR CmdLine );
extern PCHAR GetFreeLoaderVersionString();
extern ULONG CacheSizeLimit;
of_proxy ofproxy;
void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0;
void *PageDirectoryStart, *PageDirectoryEnd;
static int chosen_package, stdin_handle, part_handle = -1;
BOOLEAN AcpiPresent = FALSE;
char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
jmp_buf jmp;
volatile char *video_mem = 0;
boot_infos_t BootInfo;
void le_swap( void *start_addr_v,
void *end_addr_v,
@@ -183,56 +184,160 @@ VOID PpcVideoSync() {
printf( "Sync\n" );
}
VOID PpcVideoPrepareForReactOS() {
printf( "PrepareForReactOS\n");
static int prom_next_node(int *nodep)
{
int node;
if ((node = *nodep) != 0
&& (*nodep = ofw_child(node)) != 0)
return 1;
if ((*nodep = ofw_peer(node)) != 0)
return 1;
for (;;) {
if ((node = ofw_parent(node)) == 0)
return 0;
if ((*nodep = ofw_peer(node)) != 0)
return 1;
}
}
VOID PpcVideoPrepareForReactOS() {
int i, j, display_handle, display_size = 0;
int node, ret, elts;
pci_reg_property display_regs[8];
char type[256], path[256], name[256];
for( node = ofw_finddevice("/"); prom_next_node(&node); ) {
memset(type, 0, sizeof(type));
memset(path, 0, sizeof(path));
ret = ofw_getprop(node, "name", name, sizeof(name));
if(ofw_getprop(node, "device_type", type, sizeof(type)) <= 0) {
printf("Could not get type for node %x\n", node);
continue;
}
printf("Node %x ret %d name %s type %s\n", node, ret, name, type);
if(strcmp(type, "display") == 0) break;
}
if(!node) return;
if(ofw_package_to_path(node, path, sizeof(path)) < 0) {
printf("could not get path for display package %x\n", node);
return;
}
printf("Opening display package: %s\n", path);
display_handle = ofw_open(path);
printf("display handle %x\n", display_handle);
BootInfo.dispDeviceRect[0] = BootInfo.dispDeviceRect[1] = 0;
ofw_getprop(display_handle, "width",
(void *)&BootInfo.dispDeviceRect[2], sizeof(int));
ofw_getprop(display_handle, "height",
(void *)&BootInfo.dispDeviceRect[3], sizeof(int));
ofw_getprop(display_handle, "depth",
(void *)&BootInfo.dispDeviceDepth, sizeof(int));
ofw_getprop(display_handle, "linebytes",
(void *)&BootInfo.dispDeviceRowBytes, sizeof(int));
if(ofw_getprop
(display_handle,
"address",
(void *)&BootInfo.dispDeviceBase,
sizeof(BootInfo.dispDeviceBase)) > 0) {
goto finish;
}
if((elts = ofw_getprop(display_handle,
"assigned-addresses",
(void *)display_regs,
sizeof(display_regs))) <= 0) {
printf("Could not get assigned addresses\n");
return;
}
elts /= sizeof(display_regs[0]);
for( i = 0; i < elts; i++ ) {
display_size = display_regs[i].size_lo;
if( display_size >= (1 << 20) ) {
BootInfo.dispDeviceBase = (void *)display_regs[i].addr.a_lo;
/* Map pages for display at some location */
BootInfo.logicalDisplayBase = (void *)0xc0000000;
for( i = 0; i < display_size; i += (1 << 12) ) {
InsertPageEntry((ULONG_PTR)((PCHAR)BootInfo.logicalDisplayBase)+i,
(ULONG_PTR)((PCHAR)BootInfo.dispDeviceBase)+i);
}
}
}
finish:
/* Draw something ... */
elts = 0;
for( i = 0; i < BootInfo.dispDeviceRect[3]; i++ ) {
for( j = 0; j < BootInfo.dispDeviceRect[2]; j++ ) {
((PCHAR)BootInfo.logicalDisplayBase)
[(j * (BootInfo.dispDeviceDepth/8)) +
(i * (BootInfo.dispDeviceRowBytes))] = elts++;
}
}
}
/*
* Get memory the proper openfirmware way
*/
ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize ) {
int i, memhandle, mmuhandle, returned, total = 0, num_mem = 0;
int memdata[256];
int i, memhandle, returned, total = 0, slots = 0;
int memdata[0x40];
printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
if( mem_base ) {
BiosMemoryMap[0].Type = MEMTYPE_USABLE;
BiosMemoryMap[0].BaseAddress = (ULONG)mem_base;
BiosMemoryMap[0].Length = TOTAL_HEAP_NEEDED;
printf("[cached] returning 1 element\n");
return 1;
}
ofw_getprop(chosen_package, "memory",
(char *)&memhandle, sizeof(memhandle));
ofw_getprop(chosen_package, "mmu",
(char *)&mmuhandle, sizeof(mmuhandle));
memhandle = ofw_finddevice("/memory");
returned = ofw_getprop(memhandle, "available",
(char *)memdata, sizeof(memdata));
/* We need to leave some for open firmware. Let's claim up to 16 megs
* for now */
printf("Returned data: %d\n", returned);
if( returned == -1 ) {
printf("getprop /memory[@reg] failed\n");
return 0;
}
for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) {
BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE;
BiosMemoryMap[num_mem].BaseAddress = memdata[i];
mem_base = (void *)memdata[i];
BiosMemoryMap[num_mem].Length = memdata[i+1];
if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED &&
total < TOTAL_HEAP_NEEDED ) {
BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED;
ofw_claim(BiosMemoryMap[num_mem].BaseAddress,
BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */
total += BiosMemoryMap[0].Length;
num_mem++;
for( i = 0; i < returned; i++ ) {
printf("%x ", memdata[i]);
}
printf("\n");
for( i = 0; i < returned / 2; i++ ) {
BiosMemoryMap[slots].Type = MEMTYPE_USABLE;
BiosMemoryMap[slots].BaseAddress = REV(memdata[i*2]);
BiosMemoryMap[slots].Length = REV(memdata[i*2+1]);
printf("MemoryMap[%d] = (%x:%x)\n",
i,
(int)BiosMemoryMap[slots].BaseAddress,
(int)BiosMemoryMap[slots].Length);
if( BiosMemoryMap[slots].Length &&
ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
(int)BiosMemoryMap[slots].Length,
0x1000) ) {
total += BiosMemoryMap[slots].Length;
slots++;
}
}
printf( "Returning memory map (%dk total)\n", total / 1024 );
return num_mem;
return slots;
}
/* Strategy:
@@ -304,6 +409,7 @@ BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512));
return FALSE;
}
rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) );
return rlen > 0;
}
@@ -374,36 +480,27 @@ BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) {
return TRUE;
}
extern int _bss;
typedef unsigned int uint32_t;
void PpcInit( of_proxy the_ofproxy ) {
int len, stdin_handle_chosen;
ofproxy = the_ofproxy;
ofw_print_string("Freeldr PowerPC Init\n");
//SetPhys(0x900, (19 << 26) | (50 << 1));
chosen_package = ofw_finddevice( "/chosen" );
ofw_print_string("Freeldr: chosen_package is ");
ofw_print_number(chosen_package);
ofw_print_string("\n");
ofw_getprop( chosen_package, "stdin",
(char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) );
(char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) );
ofw_print_string("Freeldr: stdin_handle is ");
ofw_print_number(stdin_handle_chosen);
ofw_print_string("\n");
stdin_handle = stdin_handle_chosen;
/* stdin_handle = REV(stdin_handle); */
stdin_handle = REV(stdin_handle_chosen);
MachVtbl.ConsPutChar = PpcPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
printf( "stdin_handle is %x\n", stdin_handle );
printf( "chosen_package %x, stdin_handle is %x\n",
chosen_package, stdin_handle );
printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0));
printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0));
@@ -444,6 +541,8 @@ 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;