mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 16:03:00 +00:00
[FREELDR][NTOS][HALPPC][SDK] Remove PowerPC code
Remove PowerPC-related code from the kernel, HAL, SDK and Freeloader.
This commit is contained in:
parent
911fc3cf5b
commit
6ef6fabfc5
88 changed files with 0 additions and 17348 deletions
|
@ -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
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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];
|
||||
}
|
|
@ -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
|
|
@ -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( "" );
|
||||
}
|
||||
|
|
@ -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 );
|
|
@ -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);
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue