[FREELDR][NTOS][HALPPC][SDK] Remove PowerPC code

Remove PowerPC-related code from the kernel, HAL, SDK and
Freeloader.
This commit is contained in:
Victor Perevertkin 2021-08-08 01:50:20 +03:00
parent 911fc3cf5b
commit 6ef6fabfc5
No known key found for this signature in database
GPG key ID: C750B7222E9C7830
88 changed files with 0 additions and 17348 deletions

View file

@ -1,111 +0,0 @@
.section ".text"
.extern PpcInit
.globl _start
.globl call_ofw
_start:
sync
isync
lis %r1,stackend@ha
addi %r1,%r1,stackend@l
/* Store ofw call addr */
mr %r21,%r5
lis %r10,ofw_call_addr@ha
stw %r5,ofw_call_addr@l(%r10)
bl zero_registers
/* Zero CTR */
mtcr %r31
lis %r3,PpcInit@ha
addi %r3,%r3,PpcInit@l
mtlr %r3
/* Check for ofw */
lis %r3,ofw_call_addr@ha
lwz %r3,ofw_call_addr@l(%r3)
cmpw %r3,%r31 /* Zero? */
mr %r3,%r31
beq initfp
lis %r3,call_ofw@ha
addi %r3,%r3,call_ofw@l
b bootme
initfp:
/* Enabling FP at this point won't hurt, and the varargs scheme we're
* using now requires it. */
mfmsr %r0
ori %r0,%r0,8192
mtmsr %r0
bootme:
blr
zero_registers:
xor %r2,%r2,%r2
mr %r0,%r2
mr %r3,%r2
mr %r4,%r2
mr %r5,%r2
mr %r6,%r2
mr %r7,%r2
mr %r8,%r2
mr %r9,%r2
mr %r10,%r2
mr %r11,%r2
mr %r12,%r2
mr %r13,%r2
mr %r14,%r2
mr %r15,%r2
mr %r12,%r2
mr %r13,%r2
mr %r14,%r2
mr %r15,%r2
mr %r16,%r2
mr %r17,%r2
mr %r18,%r2
mr %r19,%r2
mr %r20,%r2
mr %r21,%r2
mr %r22,%r2
mr %r23,%r2
mr %r24,%r2
mr %r25,%r2
mr %r26,%r2
mr %r27,%r2
mr %r28,%r2
mr %r29,%r2
mr %r30,%r2
mr %r31,%r2
blr
ofw_memory_size:
.long 0
.long 0
.long 0
.long 0
.align 4
stack:
.space 0x4000
stackend:
.long 0,0,0,0
.globl _bss
.section ".bss2"
_bss:
.long 0
.align 4

View file

@ -1,105 +0,0 @@
#pragma once
#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(void);

View file

@ -1,348 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _NTSYSTEM_
#include <freeldr.h>
#include <debug.h>
#define DbgPrint printf
extern PVOID KernelBase;
extern PVOID KernelMemory;
PVOID
NTAPI
LdrPEGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
USHORT Hint);
/* FUNCTIONS *****************************************************************/
PLOADER_MODULE
NTAPI
LdrGetModuleObject(PCHAR ModuleName)
{
ULONG i;
for (i = 0; i < LoaderBlock.ModsCount; i++)
{
if (strstr(_strupr((PCHAR)reactos_modules[i].String), _strupr(ModuleName)))
{
return &reactos_modules[i];
}
}
return NULL;
}
PVOID
NTAPI
LdrPEFixupForward(IN PCHAR ForwardName)
{
CHAR NameBuffer[128];
PCHAR p;
PLOADER_MODULE ModuleObject;
strcpy(NameBuffer, ForwardName);
p = strchr(NameBuffer, '.');
if (p == NULL) return NULL;
*p = 0;
ModuleObject = LdrGetModuleObject(NameBuffer);
if (!ModuleObject)
{
DbgPrint("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
return NULL;
}
return LdrPEGetExportByName((PVOID)ModuleObject->ModStart, (PUCHAR)(p + 1), 0xffff);
}
PVOID
NTAPI
LdrPEGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
USHORT Hint)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
PULONG * ExFunctions;
PULONG * ExNames;
USHORT * ExOrdinals;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
LONG minn, maxn, mid, res;
ULONG ExportDirSize;
/* HAL and NTOS use a virtual address, switch it to physical mode */
if ((ULONG_PTR)BaseAddress & 0x80000000)
{
BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - KSEG0_BASE + (ULONG)KernelMemory);
}
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
if (!ExportDir)
{
DbgPrint("LdrPEGetExportByName(): no export directory!\n");
return NULL;
}
/* The symbol names may be missing entirely */
if (!ExportDir->AddressOfNames)
{
DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n");
return NULL;
}
/*
* Get header pointers
*/
ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
/*
* Check the hint first
*/
if (Hint < ExportDir->NumberOfNames)
{
ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
{
Function = LdrPEFixupForward((PCHAR)Function);
if (Function == NULL)
{
DbgPrint("LdrPEGetExportByName(): failed to find %s\n", Function);
}
return Function;
}
if (Function != NULL) return Function;
}
}
/*
* Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
{
Function = LdrPEFixupForward((PCHAR)Function);
if (Function == NULL)
{
DbgPrint("1: failed to find %s\n", Function);
}
return Function;
}
if (Function != NULL)
{
return Function;
}
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
/* Fall back on unsorted */
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
ExName = RVA(BaseAddress, ExNames[minn]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[minn];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
{
Function = LdrPEFixupForward((PCHAR)Function);
if (Function == NULL)
{
DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
{
return Function;
}
DbgPrint("Failed to get function %s\n", SymbolName);
}
minn++;
}
DbgPrint("2: failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
NTSTATUS
NTAPI
LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
PLOADER_MODULE LoaderModule,
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
{
PVOID* ImportAddressList;
PULONG FunctionNameList;
if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the import address list. */
ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
}
else
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
}
/* Walk through function list and fixup addresses. */
while (*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000)
{
DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
return STATUS_UNSUCCESSFUL;
}
else
{
IMAGE_IMPORT_BY_NAME *pe_name;
pe_name = RVA(DriverBase, *FunctionNameList);
*ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);
/* Fixup the address to be virtual */
*ImportAddressList = (PVOID)(ULONG_PTR)*ImportAddressList + (ULONG_PTR)KernelBase - (ULONG_PTR)KernelMemory;
//DbgPrint("Looked for: %s and found: %x\n", pe_name->Name, *ImportAddressList);
if ((*ImportAddressList) == NULL)
{
DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
return STATUS_UNSUCCESSFUL;
}
}
ImportAddressList++;
FunctionNameList++;
}
return STATUS_SUCCESS;
}
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
NTSTATUS
NTAPI
LdrPEGetOrLoadModule(IN PCHAR ModuleName,
IN PCHAR ImportedName,
IN PLOADER_MODULE* ImportedModule)
{
NTSTATUS Status = STATUS_SUCCESS;
*ImportedModule = LdrGetModuleObject(ImportedName);
if (*ImportedModule == NULL)
{
/*
* For now, we only support import-loading the HAL.
* Later, FrLdrLoadDriver should be made to share the same
* code, and we'll just call it instead.
*/
FrLdrLoadDriver(ImportedName, 0);
/* Return the new module */
*ImportedModule = LdrGetModuleObject(ImportedName);
if (*ImportedModule == NULL)
{
DbgPrint("Error loading import: %s\n", ImportedName);
return STATUS_UNSUCCESSFUL;
}
}
return Status;
}
NTSTATUS
NTAPI
LdrPEFixupImports(IN PVOID DllBase,
IN PCHAR DllName)
{
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PCHAR ImportedName;
NTSTATUS Status;
PLOADER_MODULE ImportedModule;
ULONG Size;
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&Size);
while (ImportModuleDirectory && ImportModuleDirectory->Name)
{
/* Check to make sure that import lib is kernel */
ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
//DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName);
Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
if (!NT_SUCCESS(Status)) return Status;
Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
if (!NT_SUCCESS(Status)) return Status;
//DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName);
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
}

View file

@ -1,555 +0,0 @@
/*
* FreeLoader PowerPC Part
* Copyright (C) 2005 Art Yerkes
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "freeldr.h"
#include "machine.h"
#include "ppcmmu/mmu.h"
#include "of.h"
#include "prep.h"
#include "compat.h"
extern void BootMain( PSTR CmdLine );
extern ULONG CacheSizeLimit;
of_proxy ofproxy;
void *PageDirectoryStart, *PageDirectoryEnd;
static int chosen_package, stdin_handle, stdout_handle, part_handle = -1;
int mmu_handle = 0;
int claimed[4];
BOOLEAN AcpiPresent = FALSE;
CHAR FrLdrBootPath[MAX_PATH] = "", BootPart[MAX_PATH] = "", CmdLine[MAX_PATH] = "bootprep";
jmp_buf jmp;
volatile char *video_mem = 0;
void PpcOfwPutChar( int ch ) {
char buf[3];
if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; }
else { buf[0] = ch; buf[1] = 0; }
buf[2] = 0;
ofw_write(stdout_handle, buf, strlen(buf));
}
int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
static char buf[256];
int next = 0;
int gotname = 0;
int match = 0;
int i;
next = ofw_child( parent );
//printf( "next = %x\n", next );
gotname = ofw_getprop(parent, "name", buf, 256);
//printf( "gotname = %d\n", gotname );
match = !strncmp(buf, devname, strlen(devname));
if( !nth && match ) return parent;
for( i = 0; i < depth; i++ ) PpcOfwPutChar( ' ' );
if( depth == 1 ) {
if( gotname > 0 ) {
printf( "%c Name: %s\n", match ? '*' : ' ', buf );
} else {
printf( "- No name attribute for %x\n", parent );
}
}
while( !match && next ) {
i = PpcFindDevice( depth+1, next, devname, nth );
if( i ) return i;
next = ofw_peer( next );
}
return 0;
}
BOOLEAN PpcConsKbHit() {
return FALSE;
}
int PpcConsGetCh() {
char buf;
ofw_read( stdin_handle, &buf, 1 );
return buf;
}
void PpcVideoClearScreen( UCHAR Attr ) {
}
VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
*Width = 80;
*Height = 25;
*Depth = 16;
}
ULONG PpcVideoGetBufferSize() {
ULONG Width, Height, Depth;
MachVideoGetDisplaySize( &Width, &Height, &Depth );
return Width * Height * Depth / 8;
}
VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
//printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
if( Init && !video_mem ) {
video_mem = MmAllocateMemory( PpcVideoGetBufferSize() );
}
return VideoTextMode;
}
VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) {
printf("SetTextCursorPosition(%d,%d)\n", X,Y);
}
VOID PpcVideoHideShowTextCursor( BOOLEAN Show ) {
printf("HideShowTextCursor(%s)\n", Show ? "true" : "false");
}
VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) {
printf( "\033[%d;%dH%c", Y, X, Ch );
}
VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
int i,j;
ULONG w,h,d;
PCHAR ChBuf = Buffer;
int offset = 0;
MachVideoGetDisplaySize( &w, &h, &d );
for( i = 0; i < h; i++ ) {
for( j = 0; j < w; j++ ) {
offset = (j * 2) + (i * w * 2);
if( ChBuf[offset] != video_mem[offset] ) {
video_mem[offset] = ChBuf[offset];
MachVideoPutChar(ChBuf[offset],0,j+1,i+1);
}
}
}
}
BOOLEAN PpcVideoIsPaletteFixed() {
return FALSE;
}
VOID PpcVideoSetPaletteColor( UCHAR Color,
UCHAR Red, UCHAR Green, UCHAR Blue ) {
printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue );
}
VOID PpcVideoGetPaletteColor( UCHAR Color,
UCHAR *Red, UCHAR *Green, UCHAR *Blue ) {
printf( "GetPaletteColor(%x)\n", Color);
}
VOID PpcVideoSync() {
printf( "Sync\n" );
}
int mmu_initialized = 0;
int mem_range_end;
VOID PpcInitializeMmu()
{
if(!mmu_initialized)
{
MmuInit();
MmuDbgInit(0, 0x800003f8);
MmuSetMemorySize(mem_range_end);
//MmuDbgEnter(0x20);
mmu_initialized = 1;
}
}
ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize );
/*
* Get memory the proper openfirmware way
*/
ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize ) {
int i, memhandle, total = 0, slots = 0, last = 0x40000, allocstart = 0x1000000;
int regdata[0x40];
printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
memhandle = ofw_finddevice("/memory");
ofw_getprop(memhandle, "reg", (char *)regdata, sizeof(regdata));
/* Try to claim some memory in usable blocks. Try to get some 8mb bits */
for( i = 0; i < sizeof(claimed) / sizeof(claimed[0]); ) {
if (!claimed[i])
claimed[i] = ofw_claim(allocstart, 8 * 1024 * 1024, 0x1000);
allocstart += 8 * 1024 * 1024;
if (claimed[i]) {
if (last < claimed[i]) {
BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim;
BiosMemoryMap[slots].BaseAddress = last;
BiosMemoryMap[slots].Length = claimed[i] - last;
slots++;
}
BiosMemoryMap[slots].Type = BiosMemoryUsable;
BiosMemoryMap[slots].BaseAddress = claimed[i];
BiosMemoryMap[slots].Length = 8 * 1024 * 1024;
total += BiosMemoryMap[slots].Length;
last =
BiosMemoryMap[slots].BaseAddress +
BiosMemoryMap[slots].Length;
slots++;
i++;
}
}
/* Get the rest until the end of the memory object as we see it */
if (last < regdata[1]) {
BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim;
BiosMemoryMap[slots].BaseAddress = last;
BiosMemoryMap[slots].Length = regdata[1] - last;
slots++;
}
for (i = 0; i < slots; i++) {
printf("MemoryMap[%d] = (%x:%x)\n",
i,
(int)BiosMemoryMap[i].BaseAddress,
(int)BiosMemoryMap[i].Length);
}
mem_range_end = regdata[1];
printf( "Returning memory map (%d entries, %dk free, %dk total ram)\n",
slots, total / 1024, regdata[1] / 1024 );
return slots;
}
BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
ULONG SectorCount, PVOID Buffer ) {
int rlen = 0;
if( part_handle == -1 ) {
part_handle = ofw_open( BootPart );
if( part_handle == -1 ) {
printf("Could not open any disk devices we know about\n");
return FALSE;
}
}
if( part_handle == -1 ) {
printf("Got partition handle %x\n", part_handle);
return FALSE;
}
if( ofw_seek( part_handle,
(ULONG)(SectorNumber >> 25),
(ULONG)((SectorNumber * 512) & 0xffffffff) ) ) {
printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512));
return FALSE;
}
rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) );
return rlen > 0;
}
BOOLEAN PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY DriveGeometry ) {
printf("GetGeometry(%d)\n", DriveNumber);
DriveGeometry->BytesPerSector = 512;
DriveGeometry->Heads = 16;
DriveGeometry->Sectors = 63;
return TRUE;
}
ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
printf("GetCacheableBlockCount\n");
return 1;
}
TIMEINFO*
PpcGetTime(VOID)
{
static TIMEINFO TimeInfo;
//printf("PpcGetTime\n");
return &TimeInfo;
}
VOID NarrowToWide(WCHAR *wide_name, char *name)
{
char *copy_name;
WCHAR *wide_name_ptr;
for (wide_name_ptr = wide_name, copy_name = name;
(*wide_name_ptr = *copy_name);
wide_name_ptr++, copy_name++);
}
/* Recursively copy the device tree into our representation
* It'll be passed to HAL.
*
* When NT was first done on PPC, it was on PReP hardware, which is very
* like PC hardware (really, just a PPC on a PC motherboard). HAL can guess
* the addresses of needed resources in this scheme as it can on x86.
*
* Most PPC hardware doesn't assign fixed addresses to hardware, which is
* the problem that open firmware partially solves. It allows hardware makers
* much more leeway in building PPC systems. Unfortunately, because
* openfirmware as originally specified neither captures nor standardizes
* all possible information, and also because of bugs, most OSs use a hybrid
* configuration scheme that relies both on verification of devices and
* recording information from openfirmware to be treated as hints.
*/
VOID OfwCopyDeviceTree
(PCONFIGURATION_COMPONENT_DATA ParentKey,
char *name,
int innode,
ULONG *BusNumber,
ULONG *DiskController,
ULONG *DiskNumber)
{
int proplen = 0, node = innode;
char *prev_name, cur_name[64], data[256], *slash, devtype[64];
wchar_t wide_name[64];
PCONFIGURATION_COMPONENT_DATA NewKey;
NarrowToWide(wide_name, name);
/* Create a key for this device */
FldrCreateComponentKey
(ParentKey,
AdapterClass,
MultiFunctionAdapter,
0,
0,
(ULONG)-1,
NULL,
NULL,
0,
&NewKey);
/* Add properties */
for (prev_name = ""; ofw_nextprop(node, prev_name, cur_name) == 1; )
{
proplen = ofw_getproplen(node, cur_name);
if (proplen > 256 || proplen < 0)
{
printf("Warning: not getting prop %s (too long: %d)\n",
cur_name, proplen);
continue;
}
ofw_getprop(node, cur_name, data, sizeof(data));
/* Get device type so we can examine it */
if (!strcmp(cur_name, "device_type"))
strcpy(devtype, (char *)data);
NarrowToWide(wide_name, cur_name);
//RegSetValue(NewKey, wide_name, REG_BINARY, data, proplen);
strcpy(data, cur_name);
prev_name = data;
}
#if 0
/* Special device handling */
if (!strcmp(devtype, "ata"))
{
OfwHandleDiskController(NewKey, node, *DiskController);
(*DiskController)++;
*DiskNumber = 0;
}
else if (!strcmp(devtype, "disk"))
{
OfwHandleDiskObject(NewKey, node, *DiskController, *DiskNumber);
(*DiskNumber)++;
}
#endif
/* Subdevices */
for (node = ofw_child(node); node; node = ofw_peer(node))
{
ofw_package_to_path(node, data, sizeof(data));
slash = strrchr(data, '/');
if (slash) slash++; else continue;
OfwCopyDeviceTree
(NewKey, slash, node, BusNumber, DiskController, DiskNumber);
}
}
PCONFIGURATION_COMPONENT_DATA PpcHwDetect() {
PCONFIGURATION_COMPONENT_DATA RootKey;
ULONG BusNumber = 0, DiskController = 0, DiskNumber = 0;
int node = ofw_finddevice("/");
FldrCreateSystemKey(&RootKey);
OfwCopyDeviceTree(RootKey,"/",node,&BusNumber,&DiskController,&DiskNumber);
return RootKey;
}
VOID
PpcHwIdle(VOID)
{
/* UNIMPLEMENTED */
}
void PpcDefaultMachVtbl()
{
MachVtbl.ConsPutChar = PpcOfwPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = PpcVideoGetBufferSize;
MachVtbl.VideoSetTextCursorPosition = PpcVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor;
MachVtbl.VideoPutChar = PpcVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM =
PpcVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = PpcVideoGetPaletteColor;
MachVtbl.VideoSync = PpcVideoSync;
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors;
MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = PpcDiskGetCacheableBlockCount;
MachVtbl.GetTime = PpcGetTime;
MachVtbl.HwDetect = PpcHwDetect;
MachVtbl.HwIdle = PpcHwIdle;
}
void PpcOfwInit()
{
chosen_package = ofw_finddevice( "/chosen" );
ofw_getprop(chosen_package, "bootargs",
CmdLine, sizeof(CmdLine));
ofw_getprop( chosen_package, "stdin",
(char *)&stdin_handle, sizeof(stdin_handle) );
ofw_getprop( chosen_package, "stdout",
(char *)&stdout_handle, sizeof(stdout_handle) );
ofw_getprop( chosen_package, "mmu",
(char *)&mmu_handle, sizeof(mmu_handle) );
// Allow forcing prep for broken OFW
if(!strncmp(CmdLine, "bootprep", 8))
{
printf("Going to PREP init...\n");
ofproxy = NULL;
PpcPrepInit();
return;
}
printf( "FreeLDR version [%s]\n", FrLdrVersionString );
BootMain( CmdLine );
}
void PpcInit( of_proxy the_ofproxy ) {
// Hack to be a bit easier on ram
CacheSizeLimit = 64 * 1024;
ofproxy = the_ofproxy;
PpcDefaultMachVtbl();
if(ofproxy) PpcOfwInit();
else PpcPrepInit();
}
void MachInit(const char *CmdLine) {
int i, len;
char *sep;
BootPart[0] = 0;
FrLdrBootPath[0] = 0;
printf( "Determining boot device: [%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, ',');
if( sep )
*sep = 0;
while(CmdLine[i] && CmdLine[i]!=',') i++;
}
}
if( strlen(BootPart) == 0 ) {
if (ofproxy)
len = ofw_getprop(chosen_package, "bootpath",
FrLdrBootPath, sizeof(FrLdrBootPath));
else
len = 0;
if( len < 0 ) len = 0;
FrLdrBootPath[len] = 0;
printf( "Boot Path: %s\n", FrLdrBootPath );
sep = strrchr(FrLdrBootPath, ',');
strcpy(BootPart, FrLdrBootPath);
if( sep ) {
BootPart[sep - FrLdrBootPath] = 0;
}
}
printf( "FreeLDR starting (boot partition: %s)\n", BootPart );
}
void beep() {
}
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address) {
return GetPhysByte(((ULONG)Address)+0x80000000);
}
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
SetPhysByte(((ULONG)Address)+0x80000000, Value);
}
VOID __cdecl BootLinuxKernel(
IN ULONG KernelSize,
IN PVOID KernelCurrentLoadAddress,
IN PVOID KernelTargetLoadAddress,
IN UCHAR DriveNumber,
IN ULONG PartitionNumber)
{
ofw_exit();
}
VOID __cdecl ChainLoadBiosBootSectorCode(
IN UCHAR BootDrive OPTIONAL,
IN ULONG BootPartition OPTIONAL)
{
ofw_exit();
}
void DbgBreakPoint() {
__asm__("twi 31,0,0");
}

View file

@ -1,852 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <freeldr.h>
#include <elf/elf.h>
#include <elf/reactos.h>
#include <of.h>
#include "ppcmmu/mmu.h"
#include "compat.h"
#include <debug.h>
/* We'll check this to see if we're in OFW land */
extern of_proxy ofproxy;
PVOID KernelMemory = NULL;
/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
#define PFN_SHIFT 12
/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */
#define PDE_SHIFT 22
#define PDE_SHIFT_PAE 18
#define STARTUP_BASE 0xC0000000
#define HYPERSPACE_BASE 0xC0400000
#define HYPERSPACE_PAE_BASE 0xC0800000
#define APIC_BASE 0xFEC00000
#define KPCR_BASE 0xFF000000
#define LowMemPageTableIndex 0
#define StartupPageTableIndex (STARTUP_BASE >> 22)
#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22)
#define KpcrPageTableIndex (KPCR_BASE >> 22)
#define ApicPageTableIndex (APIC_BASE >> 22)
#define BAT_GRANULARITY (64 * 1024)
#define KernelMemorySize (8 * 1024 * 1024)
#define XROUNDUP(x,n) ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
#define TAG_MBOOT 'oobM'
char reactos_module_strings[64][256]; // Array to hold module names
/* Load Address of Next Module */
ULONG_PTR NextModuleBase = 0;
/* Currently Opened Module */
PLOADER_MODULE CurrentModule = NULL;
/* Unrelocated Kernel Base in Virtual Memory */
ULONG_PTR KernelBase;
/* Wether PAE is to be used or not */
BOOLEAN PaeModeEnabled;
/* Kernel Entrypoint in Physical Memory */
ULONG_PTR KernelEntryPoint;
/* Dummy to bring in memmove */
PVOID memmove_dummy = memmove;
PLOADER_MODULE
NTAPI
LdrGetModuleObject(PCHAR ModuleName);
NTSTATUS
NTAPI
LdrPEFixupImports(IN PVOID DllBase,
IN PCHAR DllName);
VOID PpcInitializeMmu(int max);
/* FUNCTIONS *****************************************************************/
/*++
* FrLdrStartup
* INTERNAL
*
* Prepares the system for loading the Kernel.
*
* Params:
* Magic - Multiboot Magic
*
* Returns:
* None.
*
* Remarks:
* None.
*
*--*/
typedef void (*KernelEntryFn)( void * );
int MmuPageMiss(int trapCode, ppc_trap_frame_t *trap)
{
int i;
printf("TRAP %x\n", trapCode);
for( i = 0; i < 40; i++ )
printf("r[%d] %x\n", i, trap->gpr[i]);
printf("HALT!\n");
while(1);
}
typedef struct _ppc_map_set_t {
int mapsize;
int usecount;
ppc_map_info_t *info;
} ppc_map_set_t;
extern int mmu_handle;
paddr_t MmuTranslate(paddr_t possibly_virtual)
{
if (ofproxy)
{
/* Openfirmware takes liberties with boot-time memory.
* if you're in a unitary kernel, it's not as difficult, but since
* we rely on loading things into virtual space from here, we need
* to detect the mappings so far.
*/
int args[2];
args[0] = possibly_virtual;
args[1] = 1; /* Marker to tell we want a physical addr */
return (paddr_t)ofw_callmethod_ret("translate", mmu_handle, 2, args, 3);
}
else
{
/* Other booters don't remap ram */
return possibly_virtual;
}
}
VOID
NTAPI
FrLdrAddPageMapping(ppc_map_set_t *set, int proc, paddr_t phys, vaddr_t virt)
{
int j;
paddr_t page = ROUND_DOWN(phys, (1<<PFN_SHIFT));
if (virt == 0)
virt = ROUND_DOWN(page, (1<<PFN_SHIFT));
else
virt = ROUND_DOWN(virt, (1<<PFN_SHIFT));
page = MmuTranslate(page);
//printf("Mapping virt [%x] to phys [%x (from) %x]\n", virt, page, phys);
for( j = 0; j < set->usecount; j++ )
{
if(set->info[j].addr == page) return;
}
if (!set->mapsize)
{
set->mapsize = 0x80;
set->info = MmAllocateMemory(0x80 * sizeof(*set->info));
}
else if (set->mapsize <= set->usecount)
{
ppc_map_info_t *newinfo = MmAllocateMemory(set->mapsize * 2 * sizeof(*set->info));
memcpy(newinfo, set->info, set->mapsize * sizeof(*set->info));
MmFreeMemory(set->info);
set->info = newinfo;
set->mapsize *= 2;
}
set->info[set->usecount].flags = MMU_ALL_RW;
set->info[set->usecount].proc = proc;
set->info[set->usecount].addr = virt;
set->info[set->usecount].phys = page;
set->usecount++;
}
extern int _start[], _end[];
VOID
NTAPI
FrLdrStartup(ULONG Magic)
{
ULONG_PTR i, tmp, OldModCount = 0;
PCHAR ModHeader;
CHAR ModulesTreated[64] = { 0 };
ULONG NumberOfEntries = 0, UsedEntries = 0;
PPAGE_LOOKUP_TABLE_ITEM FreeLdrMap = MmGetMemoryMap(&NumberOfEntries);
ppc_map_set_t memmap = { };
printf("FrLdrStartup\n");
/* Disable EE */
__asm__("mfmsr %0" : "=r" (tmp));
tmp &= 0x7fff;
__asm__("mtmsr %0" : : "r" (tmp));
while(OldModCount != LoaderBlock.ModsCount)
{
printf("Added %d modules last pass\n",
LoaderBlock.ModsCount - OldModCount);
OldModCount = LoaderBlock.ModsCount;
for(i = 0; i < LoaderBlock.ModsCount; i++)
{
if (!ModulesTreated[i])
{
ModulesTreated[i] = 1;
ModHeader = ((PCHAR)reactos_modules[i].ModStart);
if(ModHeader[0] == 'M' && ModHeader[1] == 'Z')
LdrPEFixupImports
((PVOID)reactos_modules[i].ModStart,
(PCHAR)reactos_modules[i].String);
}
}
}
printf("Starting mmu\n");
PpcInitializeMmu(0);
printf("Allocating vsid 0 (kernel)\n");
MmuAllocVsid(0, 0xff00);
/* We'll use vsid 1 for freeldr (expendable) */
printf("Allocating vsid 1 (freeldr)\n");
MmuAllocVsid(1, 0xff);
printf("Mapping Freeldr Code (%x-%x)\n", _start, _end);
/* Map memory zones */
/* Freeldr itself */
for( i = (int)_start;
i < (int)_end;
i += (1<<PFN_SHIFT) ) {
FrLdrAddPageMapping(&memmap, 1, i, 0);
}
printf("KernelBase %x\n", KernelBase);
/* Heap pages -- this gets the entire freeldr heap */
for( i = 0; i < NumberOfEntries; i++ ) {
tmp = i<<PFN_SHIFT;
if (FreeLdrMap[i].PageAllocated == LoaderSystemCode) {
UsedEntries++;
if (tmp >= (ULONG)KernelMemory &&
tmp < (ULONG)KernelMemory + KernelMemorySize) {
FrLdrAddPageMapping(&memmap, 0, tmp, KernelBase + tmp - (ULONG)KernelMemory);
} else {
FrLdrAddPageMapping(&memmap, 1, tmp, 0);
}
}
}
MmuMapPage(memmap.info, memmap.usecount);
printf("Finished Mapping the Freeldr Heap (used %d pages)\n", UsedEntries);
printf("Setting initial segments\n");
MmuSetVsid(0, 8, 1);
MmuSetVsid(8, 16, 0);
printf("Segments set!\n");
MmuTurnOn((KernelEntryFn)KernelEntryPoint, &LoaderBlock);
/* Nothing more */
while(1);
}
/*++
* FrLdrSetupPae
* INTERNAL
*
* Configures PAE on a MP System, and sets the PDBR if it's supported, or if
* the system is UP.
*
* Params:
* Magic - Multiboot Magic
*
* Returns:
* None.
*
* Remarks:
* None.
*
*--*/
VOID
FASTCALL
FrLdrSetupPae(ULONG Magic)
{
}
/*++
* FrLdrGetKernelBase
* INTERNAL
*
* Gets the Kernel Base to use.
*
* Params:
*
* Returns:
* None.
*
* Remarks:
* Sets both the FreeLdr internal variable as well as the one which
* will be used by the Kernel.
*
*--*/
VOID
FASTCALL
FrLdrGetKernelBase(VOID)
{
PCHAR p;
/* Default kernel base at 2GB */
KernelBase = 0x80800000;
/* Set KernelBase */
LoaderBlock.KernelBase = 0x80000000;
/* Read Command Line */
p = (PCHAR)LoaderBlock.CommandLine;
while ((p = strchr(p, '/')) != NULL) {
/* Find "/3GB" */
if (!_strnicmp(p + 1, "3GB", 3)) {
/* Make sure there's nothing following it */
if (p[4] == ' ' || p[4] == 0) {
/* Use 3GB */
KernelBase = 0xE0000000;
LoaderBlock.KernelBase = 0xC0000000;
}
}
p++;
}
}
/*++
* FrLdrGetPaeMode
* INTERNAL
*
* Determines whether PAE mode should be enabled or not.
*
* Params:
* None.
*
* Returns:
* None.
*
* Remarks:
* None.
*
*--*/
VOID
FASTCALL
FrLdrGetPaeMode(VOID)
{
}
/*++
* FrLdrSetupPageDirectory
* INTERNAL
*
* Sets up the ReactOS Startup Page Directory.
*
* Params:
* None.
*
* Returns:
* None.
*
* Remarks:
* We are setting PDEs, but using the equivalent (for our purpose) PTE structure.
* As such, please note that PageFrameNumber == PageEntryNumber.
*
*--*/
VOID
FASTCALL
FrLdrSetupPageDirectory(VOID)
{
}
/*++
* FrLdrMapModule
* INTERNAL
*
* Loads the indicated elf image as PE. The target will appear to be
* a PE image whose ImageBase has ever been KernelAddr.
*
* Params:
* Image -- File to load
* ImageName -- Name of image for the modules list
* MemLoadAddr -- Freeldr address of module
* KernelAddr -- Kernel address of module
*--*/
#define ELF_SECTION(n) ((Elf32_Shdr*)(sptr + (n * shsize)))
#define COFF_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+(SWAPW(((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))))
BOOLEAN
NTAPI
FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG KernelAddr)
{
PIMAGE_DOS_HEADER ImageHeader = 0;
PIMAGE_NT_HEADERS NtHeader = 0;
PIMAGE_SECTION_HEADER Section;
ULONG SectionCount;
ULONG ImageSize;
INT i, j;
PLOADER_MODULE ModuleData;
//int phsize, phnum;
int shsize, shnum, relsize, SectionAddr = 0;
PCHAR sptr;
Elf32_Ehdr ehdr;
Elf32_Shdr *shdr;
LARGE_INTEGER Position;
PSTR TempName;
TempName = strrchr(ImageName, '\\');
if(TempName) TempName++; else TempName = (PSTR)ImageName;
ModuleData = LdrGetModuleObject(TempName);
if(ModuleData)
{
return TRUE;
}
if(!KernelAddr)
KernelAddr = (ULONG)NextModuleBase - (ULONG)KernelMemory + KernelBase;
if(!MemLoadAddr)
MemLoadAddr = (PCHAR)NextModuleBase;
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
//printf("Loading file (elf at %x)\n", KernelAddr);
/* Load the first 1024 bytes of the kernel image so we can read the PE header */
if (ArcRead(KernelImage, &ehdr, sizeof(ehdr), NULL) != ESUCCESS) {
/* Fail if we couldn't read */
printf("Couldn't read the elf header\n");
return FALSE;
}
/* Start by getting elf headers */
//phsize = ehdr.e_phentsize;
//phnum = ehdr.e_phnum;
shsize = ehdr.e_shentsize;
shnum = ehdr.e_shnum;
sptr = (PCHAR)FrLdrTempAlloc(shnum * shsize, TAG_MBOOT);
/* Read section headers */
Position.QuadPart = ehdr.e_shoff;
ArcSeek(KernelImage, &Position, SeekAbsolute);
ArcRead(KernelImage, sptr, shsize * shnum, NULL);
/* Now we'll get the PE Header */
for( i = 0; i < shnum; i++ )
{
shdr = ELF_SECTION(i);
shdr->sh_addr = 0;
/* Find the PE Header */
if (shdr->sh_type == TYPE_PEHEADER)
{
Position.QuadPart = shdr->sh_offset;
ArcSeek(KernelImage, &Position, SeekAbsolute);
ArcRead(KernelImage, MemLoadAddr, shdr->sh_size, NULL);
ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
#if 0
printf("NtHeader at %x\n", SWAPD(ImageHeader->e_lfanew));
printf("SectionAlignment %x\n",
SWAPD(NtHeader->OptionalHeader.SectionAlignment));
SectionAddr = ROUND_UP
(shdr->sh_size, SWAPD(NtHeader->OptionalHeader.SectionAlignment));
printf("Header ends at %x\n", SectionAddr);
#endif
break;
}
}
if(i == shnum)
{
printf("No peheader section encountered :-(\n");
return 0;
}
#if 0
else
{
printf("DOS SIG: %s\n", (PCHAR)MemLoadAddr);
}
#endif
/* Save the Image Base */
NtHeader->OptionalHeader.ImageBase = SWAPD(KernelAddr);
/* Load the file image */
Section = COFF_FIRST_SECTION(NtHeader);
SectionCount = SWAPW(NtHeader->FileHeader.NumberOfSections);
/* Walk each section */
for (i=0; i < SectionCount; i++, Section++)
{
shdr = ELF_SECTION((SWAPD(Section->PointerToRawData)+1));
shdr->sh_addr = SectionAddr = SWAPD(Section->VirtualAddress);
shdr->sh_addr += KernelAddr;
Section->PointerToRawData = SWAPD((Section->VirtualAddress - KernelAddr));
if (shdr->sh_type != SHT_NOBITS)
{
/* Content area */
printf("Loading section %d at %x (real: %x:%d)\n", i, KernelAddr + SectionAddr, MemLoadAddr+SectionAddr, shdr->sh_size);
Position.QuadPart = shdr->sh_offset;
ArcSeek(KernelImage, &Position, SeekAbsolute);
ArcRead(KernelImage, MemLoadAddr + SectionAddr, shdr->sh_size, NULL);
}
else
{
/* Zero it out */
printf("BSS section %d at %x\n", i, KernelAddr + SectionAddr);
memset(MemLoadAddr + SectionAddr, 0,
ROUND_UP(shdr->sh_size,
SWAPD(NtHeader->OptionalHeader.SectionAlignment)));
}
}
ImageSize = SWAPD(NtHeader->OptionalHeader.SizeOfImage);
printf("Total image size is %x\n", ImageSize);
/* Handle relocation sections */
for (i = 0; i < shnum; i++) {
Elf32_Rela reloc = { };
ULONG *Target32;
USHORT *Target16;
int numreloc, relstart, targetSection;
Elf32_Sym symbol;
PCHAR RelocSection, SymbolSection;
shdr = ELF_SECTION(i);
/* Only relocs here */
if((shdr->sh_type != SHT_REL) &&
(shdr->sh_type != SHT_RELA)) continue;
relstart = shdr->sh_offset;
relsize = shdr->sh_type == SHT_RELA ? 12 : 8;
numreloc = shdr->sh_size / relsize;
targetSection = shdr->sh_info;
if (!ELF_SECTION(targetSection)->sh_addr) continue;
RelocSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
Position.QuadPart = relstart;
ArcSeek(KernelImage, &Position, SeekAbsolute);
ArcRead(KernelImage, RelocSection, shdr->sh_size, NULL);
/* Get the symbol section */
shdr = ELF_SECTION(shdr->sh_link);
SymbolSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
Position.QuadPart = shdr->sh_offset;
ArcSeek(KernelImage, &Position, SeekAbsolute);
ArcRead(KernelImage, SymbolSection, shdr->sh_size, NULL);
for(j = 0; j < numreloc; j++)
{
ULONG S,A,P;
/* Get the reloc */
memcpy(&reloc, RelocSection + (j * relsize), sizeof(reloc));
/* Get the symbol */
memcpy(&symbol, SymbolSection + (ELF32_R_SYM(reloc.r_info) * sizeof(symbol)), sizeof(symbol));
/* Compute addends */
S = symbol.st_value + ELF_SECTION(symbol.st_shndx)->sh_addr;
A = reloc.r_addend;
P = reloc.r_offset + ELF_SECTION(targetSection)->sh_addr;
#if 0
printf("Symbol[%d] %d -> %d(%x:%x) -> %x(+%x)@%x\n",
ELF32_R_TYPE(reloc.r_info),
ELF32_R_SYM(reloc.r_info),
symbol.st_shndx,
ELF_SECTION(symbol.st_shndx)->sh_addr,
symbol.st_value,
S,
A,
P);
#endif
Target32 = (ULONG*)(((PCHAR)MemLoadAddr) + (P - KernelAddr));
Target16 = (USHORT *)Target32;
switch (ELF32_R_TYPE(reloc.r_info))
{
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*Target32 = S + A;
break;
case R_PPC_REL32:
*Target32 = S + A - P;
break;
case R_PPC_UADDR32: /* Special: Treat as RVA */
*Target32 = S + A - KernelAddr;
break;
case R_PPC_ADDR24:
*Target32 = (ADDR24_MASK & (S+A)) | (*Target32 & ~ADDR24_MASK);
break;
case R_PPC_REL24:
*Target32 = (ADDR24_MASK & (S+A-P)) | (*Target32 & ~ADDR24_MASK);
break;
case R_PPC_ADDR16_LO:
*Target16 = S + A;
break;
case R_PPC_ADDR16_HA:
*Target16 = (S + A + 0x8000) >> 16;
break;
default:
break;
}
#if 0
printf("reloc[%d:%x]: (type %x sym %d val %d) off %x add %x (old %x new %x)\n",
j,
((ULONG)Target32) - ((ULONG)MemLoadAddr),
ELF32_R_TYPE(reloc.r_info),
ELF32_R_SYM(reloc.r_info),
symbol.st_value,
reloc.r_offset, reloc.r_addend,
x, *Target32);
#endif
}
FrLdrTempFree(SymbolSection, TAG_MBOOT);
FrLdrTempFree(RelocSection, TAG_MBOOT);
}
FrLdrTempFree(sptr, TAG_MBOOT);
ModuleData->ModStart = (ULONG)MemLoadAddr;
/* Increase the next Load Base */
NextModuleBase = ROUND_UP((ULONG)MemLoadAddr + ImageSize, PAGE_SIZE);
ModuleData->ModEnd = NextModuleBase;
ModuleData->String = (ULONG)MmAllocateMemory(strlen(ImageName)+1);
strcpy((PCHAR)ModuleData->String, ImageName);
printf("Module %s (%x-%x) next at %x\n",
ModuleData->String,
ModuleData->ModStart,
ModuleData->ModEnd,
NextModuleBase);
LoaderBlock.ModsCount++;
/* Return Success */
return TRUE;
}
/*++
* FrLdrMapKernel
* INTERNAL
*
* Maps the Kernel into memory, does PE Section Mapping, initializes the
* uninitialized data sections, and relocates the image.
*
* Params:
* KernelImage - FILE Structure representing the ntoskrnl image file.
*
* Returns:
* TRUE if the Kernel was mapped.
*
* Remarks:
* None.
*
*--*/
BOOLEAN
NTAPI
FrLdrMapKernel(FILE *KernelImage)
{
/* Get Kernel Base */
FrLdrGetKernelBase();
/* Allocate kernel memory */
KernelMemory = MmAllocateMemory(KernelMemorySize);
return FrLdrMapModule(KernelImage, "ntoskrnl.exe", KernelMemory, KernelBase);
}
ULONG_PTR
NTAPI
FrLdrLoadModule(FILE *ModuleImage,
PCSTR ModuleName,
PULONG ModuleSize)
{
ARC_STATUS Status;
FILEINFORMATION FileInfo;
ULONG LocalModuleSize;
ULONG_PTR ThisModuleBase = NextModuleBase;
PLOADER_MODULE ModuleData;
PSTR NameBuffer;
PSTR TempName;
/* Get current module data structure and module name string array */
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
/* Get only the Module Name */
do {
TempName = strchr(ModuleName, '\\');
if(TempName) {
ModuleName = TempName + 1;
}
} while(TempName);
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Get Module Size */
Status = ArcGetFileInformation(ModuleImage, &FileInfo);
if (Status != ESUCCESS || FileInfo.EndingAddress.HighPart != 0)
LocalModuleSize = 0;
else
LocalModuleSize = FileInfo.EndingAddress.LowPart;
/* Fill out Module Data Structure */
ModuleData->ModStart = NextModuleBase;
ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
/* Save name */
strcpy(NameBuffer, ModuleName);
ModuleData->String = (ULONG_PTR)NameBuffer;
/* Load the file image */
ArcRead(ModuleImage, (PVOID)NextModuleBase, LocalModuleSize, NULL);
/* Move to next memory block and increase Module Count */
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Return Module Size if required */
if (ModuleSize != NULL) {
*ModuleSize = LocalModuleSize;
}
printf("Module %s (%x-%x) next at %x\n",
ModuleData->String,
ModuleData->ModStart,
ModuleData->ModEnd,
NextModuleBase);
return ThisModuleBase;
}
PVOID
NTAPI
FrLdrMapImage(IN FILE *Image, IN PCHAR ShortName, IN ULONG ImageType)
{
PVOID Result = NULL;
printf("Loading image %s (type %d)\n", ShortName, ImageType);
if (ImageType == 1)
{
if(FrLdrMapKernel(Image))
Result = (PVOID)KernelMemory;
}
else
{
PVOID ModuleBase = (PVOID)NextModuleBase;
if(FrLdrMapModule(Image, ShortName, 0, 0))
Result = ModuleBase;
}
return Result;
}
ULONG_PTR
NTAPI
FrLdrCreateModule(PCSTR ModuleName)
{
PLOADER_MODULE ModuleData;
PSTR NameBuffer;
/* Get current module data structure and module name string array */
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Set up the structure */
ModuleData->ModStart = NextModuleBase;
ModuleData->ModEnd = -1;
/* Copy the name */
strcpy(NameBuffer, ModuleName);
ModuleData->String = (ULONG_PTR)NameBuffer;
/* Set the current Module */
CurrentModule = ModuleData;
/* Return Module Base Address */
return(ModuleData->ModStart);
}
BOOLEAN
NTAPI
FrLdrCloseModule(ULONG_PTR ModuleBase,
ULONG ModuleSize)
{
PLOADER_MODULE ModuleData = CurrentModule;
/* Make sure a module is opened */
if (ModuleData) {
/* Make sure this is the right module and that it hasn't been closed */
if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == MAXULONG_PTR)) {
/* Close the Module */
ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
/* Set the next Module Base and increase the number of modules */
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Close the currently opened module */
CurrentModule = NULL;
/* Success */
return(TRUE);
}
}
/* Failure path */
return(FALSE);
}

View file

@ -1,399 +0,0 @@
#include <freeldr.h>
#include "ppcmmu/mmu.h"
inline int GetMSR() {
register int res asm ("r3");
__asm__("mfmsr 3");
return res;
}
inline int GetDEC() {
register int res asm ("r3");
__asm__("mfdec 3");
return res;
}
__asm__("\t.globl GetPhys\n"
"GetPhys:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"isync\n\t"
"sync\n\t"
"lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
"mtmsr 5\n\t"
"isync\n\t"
"sync\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
__asm__("\t.globl GetPhysHalf\n"
"GetPhysHalf:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"isync\n\t"
"sync\n\t"
"lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
"mtmsr 5\n\t"
"isync\n\t"
"sync\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
__asm__("\t.globl GetPhysByte\n"
"GetPhysByte:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"isync\n\t"
"sync\n\t"
"lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
"mtmsr 5\n\t"
"isync\n\t"
"sync\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
__asm__("\t.globl SetPhys\n"
"SetPhys:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"sync\n\t"
"eieio\n\t"
"stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
"dcbst 0,3\n\t"
"mtmsr 5\n\t"
"sync\n\t"
"eieio\n\t"
"mr 3,4\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
__asm__("\t.globl SetPhysHalf\n"
"SetPhysHalf:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"sync\n\t"
"eieio\n\t"
"sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
"dcbst 0,3\n\t"
"mtmsr 5\n\t"
"sync\n\t"
"eieio\n\t"
"mr 3,4\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
__asm__("\t.globl SetPhysByte\n"
"SetPhysByte:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"sync\n\t"
"eieio\n\t"
"stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
"dcbst 0,3\n\t"
"mtmsr 5\n\t"
"sync\n\t"
"eieio\n\t"
"mr 3,4\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
inline int GetSR(int n) {
register int res asm ("r3");
switch( n ) {
case 0:
__asm__("mfsr 3,0");
break;
case 1:
__asm__("mfsr 3,1");
break;
case 2:
__asm__("mfsr 3,2");
break;
case 3:
__asm__("mfsr 3,3");
break;
case 4:
__asm__("mfsr 3,4");
break;
case 5:
__asm__("mfsr 3,5");
break;
case 6:
__asm__("mfsr 3,6");
break;
case 7:
__asm__("mfsr 3,7");
break;
case 8:
__asm__("mfsr 3,8");
break;
case 9:
__asm__("mfsr 3,9");
break;
case 10:
__asm__("mfsr 3,10");
break;
case 11:
__asm__("mfsr 3,11");
break;
case 12:
__asm__("mfsr 3,12");
break;
case 13:
__asm__("mfsr 3,13");
break;
case 14:
__asm__("mfsr 3,14");
break;
case 15:
__asm__("mfsr 3,15");
break;
}
return res;
}
inline void GetBat( int bat, int inst, int *batHi, int *batLo ) {
register int bh asm("r3"), bl asm("r4");
if( inst ) {
switch( bat ) {
case 0:
__asm__("mfibatu 3,0");
__asm__("mfibatl 4,0");
break;
case 1:
__asm__("mfibatu 3,1");
__asm__("mfibatl 4,1");
break;
case 2:
__asm__("mfibatu 3,2");
__asm__("mfibatl 4,2");
break;
case 3:
__asm__("mfibatu 3,3");
__asm__("mfibatl 4,3");
break;
}
} else {
switch( bat ) {
case 0:
__asm__("mfdbatu 3,0");
__asm__("mfdbatl 4,0");
break;
case 1:
__asm__("mfdbatu 3,1");
__asm__("mfdbatl 4,1");
break;
case 2:
__asm__("mfdbatu 3,2");
__asm__("mfdbatl 4,2");
break;
case 3:
__asm__("mfdbatu 3,3");
__asm__("mfdbatl 4,3");
break;
}
}
*batHi = bh;
*batLo = bl;
}
inline void SetBat( int bat, int inst, int batHi, int batLo ) {
register int bh asm("r3"), bl asm("r4");
bh = batHi;
bl = batLo;
if( inst ) {
switch( bat ) {
case 0:
__asm__("mtibatu 0,3");
__asm__("mtibatl 0,4");
break;
case 1:
__asm__("mtibatu 1,3");
__asm__("mtibatl 1,4");
break;
case 2:
__asm__("mtibatu 2,3");
__asm__("mtibatl 2,4");
break;
case 3:
__asm__("mtibatu 3,3");
__asm__("mtibatl 3,4");
break;
}
} else {
switch( bat ) {
case 0:
__asm__("mtdbatu 0,3");
__asm__("mtdbatl 0,4");
break;
case 1:
__asm__("mtdbatu 1,3");
__asm__("mtdbatl 1,4");
break;
case 2:
__asm__("mtdbatu 2,3");
__asm__("mtdbatl 2,4");
break;
case 3:
__asm__("mtdbatu 3,3");
__asm__("mtdbatl 3,4");
break;
}
}
__asm__("isync\n\tsync");
}
inline int GetSDR1() {
register int res asm("r3");
__asm__("mfsdr1 3");
return res;
}
inline void SetSDR1( int sdr ) {
#if 0
int i,j;
#endif
__asm__("mtsdr1 3");
#if 0
__asm__("sync");
__asm__("isync");
__asm__("ptesync");
for( i = 0; i < 256; i++ ) {
j = i << 12;
__asm__("tlbie %0,0" : : "r" (j));
}
__asm__("eieio");
__asm__("tlbsync");
__asm__("ptesync");
#endif
}
inline int BatHit( int bath, int batl, int virt ) {
int mask = 0xfffe0000 & ~((batl & 0x3f) << 17);
return (batl & 0x40) && ((virt & mask) == (bath & mask));
}
inline int BatTranslate( int bath, int batl, int virt ) {
return (virt & 0x007fffff) | (batl & 0xfffe0000);
}
/* translate address */
int PpcVirt2phys( int virt, int inst ) {
int msr = GetMSR();
int txmask = inst ? 0x20 : 0x10;
int i, bath, batl, sr, sdr1, physbase, valo;
int hash, hashmask, ptehi, ptelo, ptegaddr;
//int vahi, npteg;
int vsid, pteh, ptevsid, pteapi;
if( msr & txmask ) {
sr = GetSR( virt >> 28 );
vsid = sr & 0xfffffff;
//vahi = vsid >> 4;
valo = (vsid << 28) | (virt & 0xfffffff);
if( sr & 0x80000000 ) {
return valo;
}
for( i = 0; i < 4; i++ ) {
GetBat( i, inst, &bath, &batl );
if( BatHit( bath, batl, virt ) ) {
return BatTranslate( bath, batl, virt );
}
}
sdr1 = GetSDR1();
physbase = sdr1 & ~0xffff;
hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
//npteg = hashmask + 1;
for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
ptegaddr = ((hashmask & hash) * 64) + physbase;
for( i = 0; i < 8; i++ ) {
ptehi = GetPhys( ptegaddr + (i * 8) );
ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
ptevsid = (ptehi >> 7) & 0xffffff;
pteapi = ptehi & 0x3f;
if( (ptehi & 64) != pteh ) continue;
if( ptevsid != (vsid & 0xffffff) ) continue;
if( pteapi != ((virt >> 22) & 0x3f) ) continue;
return (ptelo & 0xfffff000) | (virt & 0xfff);
}
}
return -1;
} else {
return virt;
}
}
/* Add a new page table entry for the indicated mapping */
BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) {
int i, ptehi, ptelo;
int sdr1 = _sdr1 ? _sdr1 : GetSDR1();
int sr = GetSR( (virt >> 28) & 0xf );
int vsid = sr & 0xfffffff;
int physbase = sdr1 & ~0xffff;
int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
int valo = (vsid << 28) | (virt & 0xfffffff);
int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
int ptegaddr = ((hashmask & hash) * 64) + physbase;
for( i = 0; i < 8; i++ ) {
ptehi = GetPhys( ptegaddr + (i * 8) );
if( (slot != i) && (ptehi & 0x80000000) ) continue;
ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
ptelo = phys & ~0xfff;
SetPhys( ptegaddr + (i * 8), ptehi );
SetPhys( ptegaddr + (i * 8) + 4, ptelo );
return TRUE;
}
return FALSE;
}

View file

@ -1,26 +0,0 @@
#include <freeldr.h>
#include "of.h"
typedef struct _ofw_method_call {
const char *call_method;
int nargs;
int nrets;
const char *method_name;
int handle;
int args_rets[8];
} ofw_method_call;
extern int (*ofw_call_addr)(void *argstruct);
int ofw_callmethod_ret(const char *method, int handle, int nargs, int *args, int ret)
{
ofw_method_call callframe = { 0 };
callframe.call_method = "call-method";
callframe.nargs = nargs + 2;
callframe.nrets = ret+1;
callframe.method_name = method;
callframe.handle = handle;
memcpy(callframe.args_rets, args, sizeof(int)*nargs);
ofw_call_addr(&callframe);
return callframe.args_rets[nargs+ret];
}

View file

@ -1,48 +0,0 @@
.section .text
.globl ofw_functions
.globl ofw_call_addr
.globl call_ofw
call_ofw:
/* R3 has the function offset to call (n * 4)
* Other arg registers are unchanged. */
subi %r1,%r1,0x100
stw %r8,24(%r1)
mflr %r8
stw %r8,0(%r1)
stw %r3,4(%r1)
stw %r4,8(%r1)
stw %r5,12(%r1)
stw %r6,16(%r1)
stw %r7,20(%r1)
stw %r9,28(%r1)
stw %r10,32(%r1)
stw %r20,36(%r1)
lis %r10,ofw_functions@ha
addi %r8,%r10,ofw_functions@l
add %r8,%r3,%r8
lwz %r9,0(%r8)
mtctr %r9
mr %r3,%r4
mr %r4,%r5
mr %r5,%r6
mr %r6,%r7
mr %r7,%r8
mr %r8,%r9
/* Call ofw proxy function */
bctrl
lwz %r8,0(%r1)
mtlr %r8
lwz %r4,8(%r1)
lwz %r5,12(%r1)
lwz %r6,16(%r1)
lwz %r7,20(%r1)
lwz %r8,24(%r1)
lwz %r9,28(%r1)
lwz %r10,32(%r1)
lwz %r20,36(%r1)
addi %r1,%r1,0x100
blr

View file

@ -1,148 +0,0 @@
#include "freeldr.h"
#include "machine.h"
#include "ppcmmu/mmu.h"
#include "prep.h"
int prep_serial = 0x800003f8;
extern int mem_range_end;
void sync() { __asm__("eieio\n\tsync"); }
/* Simple serial */
void PpcPrepPutChar( int ch ) {
if( ch == 0x0a ) {
SetPhysByte(prep_serial, 0x0d);
sync();
}
SetPhysByte(prep_serial, ch);
sync();
}
BOOLEAN PpcPrepDiskReadLogicalSectors
( ULONG DriveNumber, ULONGLONG SectorNumber,
ULONG SectorCount, PVOID Buffer ) {
int secct;
for(secct = 0; secct < SectorCount; secct++)
{
ide_seek(&ide1_desc, SectorNumber + secct, 0);
ide_read(&ide1_desc, ((PCHAR)Buffer) + secct * 512, 512);
}
/* Never give up! */
return TRUE;
}
BOOLEAN PpcPrepConsKbHit()
{
return 1;
//return GetPhysByte(prep_serial+5) & 1;
}
int PpcPrepConsGetCh()
{
while(!PpcPrepConsKbHit());
return GetPhysByte(prep_serial);
}
void PpcPrepVideoClearScreen(UCHAR Attr)
{
printf("\033c");
}
VIDEODISPLAYMODE PpcPrepVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init )
{
return VideoTextMode;
}
void PpcPrepVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth )
{
*Width = 80;
*Height = 25;
*Depth = 16;
}
VOID PpcInitializeMmu(int max);
ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize )
{
// Probe memory
paddr_t physAddr;
register int oldStore = 0, newStore = 0, change = 0, oldmsr;
__asm__("mfmsr %0\n" : "=r" (oldmsr));
change = oldmsr & 0x6fff;
__asm__("mtmsr %0\n" : : "r" (change));
// Find the last ram address in physical space ... this bypasses mapping
// but could run into non-ram objects right above ram. Usually systems
// aren't designed like that though.
for (physAddr = 0x40000, change = newStore;
(physAddr < 0x80000000) && (change == newStore);
physAddr += 1 << 12)
{
oldStore = GetPhys(physAddr);
newStore = (physAddr & 0x1000) ? 0x55aa55aa : 0xaa55aa55;
SetPhys(physAddr, newStore);
change = GetPhys(physAddr);
SetPhys(physAddr, oldStore);
}
// Back off by one page
physAddr -= 0x1000;
BiosMemoryMap[0].BaseAddress = 0x30000; // End of ppcmmu
BiosMemoryMap[0].Type = BiosMemoryUsable;
BiosMemoryMap[0].Length = physAddr - BiosMemoryMap[0].BaseAddress;
__asm__("mtmsr %0\n" : : "r" (oldmsr));
mem_range_end = physAddr;
printf("Actual RAM: %d Mb\n", physAddr >> 20);
return 1;
}
/* Most PReP hardware is in standard locations, based on the corresponding
* hardware on PCs. */
PCONFIGURATION_COMPONENT_DATA PpcPrepHwDetect() {
PCONFIGURATION_COMPONENT_DATA SystemKey;
/* Create the 'System' key */
FldrCreateSystemKey(&SystemKey);
printf("DetectHardware() Done\n");
return SystemKey;
}
VOID
PpcPrepHwIdle(VOID)
{
/* UNIMPLEMENTED */
}
void PpcPrepInit()
{
MachVtbl.ConsPutChar = PpcPrepPutChar;
printf("Serial on\n");
ide_setup( &ide1_desc );
MachVtbl.DiskReadLogicalSectors = PpcPrepDiskReadLogicalSectors;
MachVtbl.ConsKbHit = PpcPrepConsKbHit;
MachVtbl.ConsGetCh = PpcPrepConsGetCh;
MachVtbl.VideoClearScreen = PpcPrepVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcPrepVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PpcPrepVideoGetDisplaySize;
MachVtbl.GetMemoryMap = PpcPrepGetMemoryMap;
MachVtbl.HwDetect = PpcPrepHwDetect;
MachVtbl.HwIdle = PcPrepHwIdle;
printf( "FreeLDR version [%s]\n", FrLdrVersionString );
BootMain( "" );
}

View file

@ -1,28 +0,0 @@
#pragma once
extern struct _pci_desc pci1_desc;
extern struct _idectl_desc ide1_desc;
extern struct _vga_desc vga1_desc;
struct _pci_bar {
unsigned long data;
};
void sync( void );
void PpcPrepInit( void );
void ide_seek( void *extension, int low, int high );
int ide_read( void *extension, char *buffer, int bytes );
void ide_setup( void *extension );
void print_bar( struct _pci_bar *bar );
void pci_setup
( PCONFIGURATION_COMPONENT_DATA pci_bus,
struct _pci_desc *pci_desc );
void pci_read_bar
( struct _pci_desc *pci_desc,
int bus, int dev, int fn, int bar,
struct _pci_bar *bar_data );
void vga_setup
( PCONFIGURATION_COMPONENT_DATA pci_bus,
struct _pci_desc *pci_desc, struct _vga_desc *vga_desc,
int bus, int dev, int fn );

View file

@ -1,106 +0,0 @@
#include "freeldr.h"
#include "machine.h"
#include "ppcmmu/mmu.h"
#include "prep.h"
#define SWAP_W(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
typedef struct _idectl_desc {
int port;
long long seekto;
int seek_cylinder, seek_head, seek_sector;
int cylinders, heads, sectors, bytespersec;
} idectl_desc;
idectl_desc ide1_desc = { 0x800001f0 };
void ide_seek( void *extension, int low, int high ) {
idectl_desc *desc = (idectl_desc *)extension;
long long seekto = ((((long long)high) << 32) | (low & 0xffffffff));
/* order = sector, head, cylinder */
desc->seek_sector = seekto % desc->sectors;
seekto /= desc->sectors;
desc->seek_head = seekto % desc->heads;
seekto /= desc->heads;
desc->seek_cylinder = seekto;
desc->seekto = seekto;
}
/* Thanks chuck moore. This is based on the color forth ide code */
/* Wait for ready */
void ide_rdy( void *extension ) {
idectl_desc *desc = (idectl_desc *)extension;
while( !(GetPhysByte(desc->port+7) & 0x40) ) sync();
}
void ide_drq( void *extension ) {
idectl_desc *desc = (idectl_desc *)extension;
while( !(GetPhysByte(desc->port+7) & 0x08) ) sync();
}
void ide_bsy( void *extension ) {
idectl_desc *desc = (idectl_desc *)extension;
while( GetPhysByte(desc->port+7) & 0x80 )
{
printf("Waiting for not busy\n");
sync();
}
}
int ide_read( void *extension, char *buffer, int bytes ) {
idectl_desc *desc = (idectl_desc *)extension;
short *databuf = (short *)buffer;
int inwords;
ide_bsy( extension );
SetPhysByte(desc->port+2, bytes / desc->bytespersec);
SetPhysByte(desc->port+3, desc->seek_sector + 1);
SetPhysByte(desc->port+4, desc->seek_cylinder);
SetPhysByte(desc->port+5, desc->seek_cylinder >> 8);
SetPhysByte(desc->port+6, desc->seek_head | 0xa0);
SetPhysByte(desc->port+7, 0x20);
for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
databuf[inwords] = GetPhysHalf(desc->port);
}
desc->seekto += desc->bytespersec;
ide_seek( extension, desc->seekto, desc->seekto >> 32 );
return bytes - (bytes % desc->bytespersec);
}
void ide_setup( void *extension ) {
idectl_desc *desc = (idectl_desc *)extension;
short identbuffer[256];
char namebuf[41];
short *databuf = (short *)identbuffer, in;
int inwords;
ide_rdy( extension );
ide_bsy( extension );
desc->bytespersec = 512;
SetPhysByte(desc->port+2, 1);
SetPhysByte(desc->port+3, 0);
SetPhysByte(desc->port+4, 0);
SetPhysByte(desc->port+5, 0);
SetPhysByte(desc->port+6, 0);
SetPhysByte(desc->port+7, 0xec);
ide_drq( extension );
for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
in = GetPhysHalf(desc->port);
databuf[inwords] = SWAP_W(in);
sync();
}
desc->cylinders = identbuffer[1];
desc->heads = identbuffer[3];
desc->sectors = identbuffer[6];
/* Debug: Write out hard disc model */
strncpy(namebuf, (char *)(identbuffer+0x1b), 41);
printf("HARD DISC MODEL: %s c,h,s %d,%d,%d\n",
namebuf, desc->cylinders, desc->heads, desc->sectors);
}

View file

@ -1,127 +0,0 @@
#include <freeldr.h>
#include "prep.h"
typedef struct _pci_cfg {
unsigned long addr;
unsigned long data;
} pci_cfg;
typedef struct _pci_desc {
pci_cfg *cfg;
} pci_desc;
pci_desc pci1_desc = { (void *)0x80000cf8 };
#define rev16(x) ((((x)>>8)&0xff)|(((x)&0xff)<<8))
#define rev32(x) ((((x)>>24)&0xff)|(((x)>>8)&0xff00)|(((x)&0xff00)<<8)|(((x)&0xff)<<24))
#define pci_addr(bus,dev,fn,reg) \
(0x80000000 | \
((bus & 0xff) << 16) | \
((dev & 0x1f) << 11) | \
((fn & 7) << 8) | \
(reg & 0xfc))
#if 0
#define pci_cfg_addr(bus,dev,fn,reg) \
((bus == 0) ? \
((1 << (dev + 16)) | \
(dev << 11) | \
(fn << 8) | \
((reg & 0xfc) | 1)) : pci_addr(bus,dev,fn,reg))
#else
#define pci_cfg_addr(bus,dev,fn,reg) pci_addr(bus,dev,fn,reg)
#endif
unsigned long pci_read( pci_desc *desc, int bus, int dev, int fn, int reg, int len ) {
sync();
unsigned long save_state = desc->cfg->addr, ret = 0;
unsigned long addr = pci_cfg_addr(bus,dev,fn,reg);
unsigned long offset = reg & 3;
desc->cfg->addr = rev32(addr);
sync();
switch( len ) {
case 4:
ret = desc->cfg->data;
break;
case 2:
ret = desc->cfg->data;
ret = (ret >> (offset << 3)) & 0xffff;
break;
case 1:
ret = desc->cfg->data;
ret = (ret >> (offset << 3)) & 0xff;
break;
}
desc->cfg->addr = save_state;
sync();
return ret;
}
void pci_read_bar( pci_desc *desc, int bus, int dev, int fn, int bar,
struct _pci_bar *bar_data ) {
bar_data->data = pci_read( desc, bus, dev, fn, 0x10 + (bar * 4), 4 );
}
/*
* Imagine: offset 3, len 1
* let oldval = 0x12345678 and val = 0xabcd1234;
* mask = ((1 << 8) - 1) << 24; // 0xff000000
* oldval = (0x12345678 & 0x00ffffff) | (0xabcd1234 & 0xff000000) = 0xab345678;
*/
void pci_write( pci_desc *desc, int bus, int dev, int fn, int reg, int len, int val ) {
unsigned long save_state = desc->cfg->addr;
unsigned long addr = pci_cfg_addr(bus,dev,fn,reg);
unsigned long offset = reg & 3;
unsigned long oldval = pci_read( desc, bus, dev, fn, reg & ~3, 4 );
unsigned long mask = ((1 << (len * 8)) - 1) << (offset << 3);
oldval = (oldval & ~mask) | ((val << (offset << 3)) & mask);
desc->cfg->addr = rev32(addr);
sync();
desc->cfg->data = rev32(oldval);
sync();
desc->cfg->addr = save_state;
sync();
}
void pci_write_bar( pci_desc *desc, int bus, int dev, int fn, int bar, struct _pci_bar *bar_data ) {
pci_write( desc, bus, dev, fn, 0x10 + (bar * 4), 4, bar_data->data );
}
void print_bar( struct _pci_bar *bar ) {
printf("BAR: %x\n", bar->data);
}
#define PCI_VENDORID 0
#define PCI_DEVICEID 2
#define PCI_HEADER_TYPE 0xe
#define PCI_BASECLASS 0xb
void pci_setup( PCONFIGURATION_COMPONENT_DATA pcibus, pci_desc *desc ) {
unsigned char type;
unsigned short vendor, device, devclass;
int funcs, bus, dev, fn;
pci1_desc.cfg = (pci_cfg *)0x80000cf8;
printf("PCI Bus:\n");
for( bus = 0; bus < 1; bus++ ) {
for( dev = 0; dev < 32; dev++ ) {
type = pci_read(desc,bus,dev,0,PCI_HEADER_TYPE,1);
vendor = pci_read(desc,bus,dev,0,PCI_VENDORID,2);
device = pci_read(desc,bus,dev,0,PCI_DEVICEID,2);
if(vendor == 0 || vendor == 0xffff) continue;
if(type & 0x80) funcs = 8; else funcs = 1;
for( fn = 0; fn < funcs; fn++ ) {
devclass = pci_read(desc,bus,dev,fn,PCI_BASECLASS,1);
printf(" %d:%d -> vendor:device:class %x:%x:%x\n",
bus, dev, vendor, device, devclass);
if( devclass == 3 ) {
printf("Setting up vga...\n");
vga_setup(pcibus,desc,&vga1_desc,bus,dev,fn);
printf("Done with vga\n");
}
}
}
}
printf("^-- end PCI\n");
}

View file

@ -1,28 +0,0 @@
#include <freeldr.h>
#include "prep.h"
struct _vga_desc {
char *port;
char *addr;
};
#define VGA_WIDTH 1024
#define VGA_HEIGHT 768
struct _vga_desc vga1_desc = { (char *)0x800003c0 };
void vga_setup( PCONFIGURATION_COMPONENT_DATA pcibus,
struct _pci_desc *desc, struct _vga_desc *vga_desc,
int bus, int dev, int fn ) {
struct _pci_bar bar_data;
int i;
for( i = 0; i < 6; i++ ) {
pci_read_bar( desc, bus, dev, fn, i, &bar_data );
print_bar( &bar_data );
if( (bar_data.data > 0x10000) || ((bar_data.data&1) == 1) ) {
vga_desc->addr = (char *)(0xc0000000 + (bar_data.data & ~0x7ff));
// BootInfo.dispDeviceBase = vga_desc->addr;
break;
}
}
}

View file

@ -1,37 +0,0 @@
/*
* FreeLoader
*
* Copyright (C) 2003 Eric Kohl
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#ifndef __REGISTRY_H
#include "../../reactos/registry.h"
#endif
/* PROTOTYPES ***************************************************************/
/* hardware.c */
VOID StallExecutionProcessor(ULONG Microseconds);
VOID HalpCalibrateStallExecution(VOID);
ULONGLONG RDTSC(VOID);
/* EOF */

View file

@ -1,16 +0,0 @@
#pragma once
#define OF_FAILED 0
#define ERR_NOT_FOUND 0xc0000010
#include "of_call.h"
#include <string.h>
typedef int (*of_proxy)
( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6 );
typedef long jmp_buf[100];
extern of_proxy ofproxy;
int setjmp( jmp_buf buf );
int longjmp( jmp_buf buf, int retval );
int ofw_callmethod_ret(const char *method, int handle, int nargs, int *args, int ret);