[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);

View file

@ -4,6 +4,4 @@ if((ARCH STREQUAL "i386") OR (ARCH STREQUAL "amd64"))
add_subdirectory(halx86)
elseif(ARCH STREQUAL "arm")
add_subdirectory(halarm)
elseif(ARCH STREQUAL "powerpc")
# add_subdirectory(halppc)
endif()

View file

@ -1,42 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/beep.c
* PURPOSE: Speaker function (it's only one)
* PROGRAMMER: Eric Kohl
* UPDATE HISTORY:
* Created 31/01/99
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* CONSTANTS *****************************************************************/
#define TIMER2 0x42
#define TIMER3 0x43
#define PORT_B 0x61
#define CLOCKFREQ 1193167
/* FUNCTIONS *****************************************************************/
/*
* FUNCTION: Beeps the speaker.
* ARGUMENTS:
* Frequency = If 0, the speaker will be switched off, otherwise
* the speaker beeps with the specified frequency.
*/
BOOLEAN
NTAPI
HalMakeBeep (
ULONG Frequency
)
{
return TRUE;
}

View file

@ -1,356 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/bus.c
* PURPOSE: Bus Support Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
ULONG HalpBusType;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
HalpRegisterKdSupportFunctions(VOID)
{
/* Register PCI Device Functions */
KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging;
KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging;
/* Register memory functions */
KdMapPhysicalMemory64 = HalpMapPhysicalMemory64;
KdUnmapVirtualAddress = HalpUnmapVirtualAddress;
/* Register ACPI stub */
KdCheckPowerButton = HalpCheckPowerButton;
}
NTSTATUS
NTAPI
HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath,
IN PUNICODE_STRING DriverClassName,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN OUT PCM_RESOURCE_LIST *AllocatedResources)
{
BUS_HANDLER BusHandler;
PAGED_CODE();
/* Only PCI is supported */
if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED;
/* Setup fake PCI Bus handler */
RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
BusHandler.BusNumber = BusNumber;
/* Call the PCI function */
return HalpAssignPCISlotResources(&BusHandler,
&BusHandler,
RegistryPath,
DriverClassName,
DriverObject,
DeviceObject,
SlotNumber,
AllocatedResources);
}
BOOLEAN
NTAPI
HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress)
{
/* Translation is easy */
TranslatedAddress->QuadPart = BusAddress.QuadPart;
return TRUE;
}
ULONG
NTAPI
HalpGetSystemInterruptVector(IN ULONG BusNumber,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity)
{
ULONG Vector = IRQ2VECTOR(BusInterruptLevel);
*Irql = (KIRQL)VECTOR2IRQL(Vector);
*Affinity = 0xFFFFFFFF;
return Vector;
}
BOOLEAN
NTAPI
HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress,
IN OUT PULONG_PTR Context,
IN BOOLEAN NextBus)
{
/* Make sure we have a context */
if (!Context) return FALSE;
/* If we have data in the context, then this shouldn't be a new lookup */
if ((*Context != 0) && (NextBus != FALSE)) return FALSE;
/* Return bus data */
TranslatedAddress->QuadPart = BusAddress.QuadPart;
/* Set context value and return success */
*Context = 1;
return TRUE;
}
VOID
NTAPI
HalpInitNonBusHandler(VOID)
{
/* These should be written by the PCI driver later, but we give defaults */
HalPciTranslateBusAddress = HalpTranslateBusAddress;
HalPciAssignSlotResources = HalpAssignSlotResources;
HalFindBusAddressTranslation = HalpFindBusAddressTranslation;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources)
{
/* Deprecated, return success */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
HalAssignSlotResources(IN PUNICODE_STRING RegistryPath,
IN PUNICODE_STRING DriverClassName,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN OUT PCM_RESOURCE_LIST *AllocatedResources)
{
/* Check the bus type */
if (BusType != PCIBus)
{
/* Call our internal handler */
return HalpAssignSlotResources(RegistryPath,
DriverClassName,
DriverObject,
DeviceObject,
BusType,
BusNumber,
SlotNumber,
AllocatedResources);
}
else
{
/* Call the PCI registered function */
return HalPciAssignSlotResources(RegistryPath,
DriverClassName,
DriverObject,
DeviceObject,
PCIBus,
BusNumber,
SlotNumber,
AllocatedResources);
}
}
/*
* @implemented
*/
ULONG
NTAPI
HalGetBusData(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length)
{
/* Call the extended function */
return HalGetBusDataByOffset(BusDataType,
BusNumber,
SlotNumber,
Buffer,
0,
Length);
}
/*
* @implemented
*/
ULONG
NTAPI
HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
BUS_HANDLER BusHandler;
/* Look as the bus type */
if (BusDataType == Cmos)
{
/* Call CMOS Function */
return HalpGetCmosData(0, SlotNumber, Buffer, Length);
}
else if (BusDataType == EisaConfiguration)
{
/* FIXME: TODO */
ASSERT(FALSE);
}
else if ((BusDataType == PCIConfiguration) &&
(HalpPCIConfigInitialized) &&
((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus)))
{
/* Setup fake PCI Bus handler */
RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
BusHandler.BusNumber = BusNumber;
/* Call PCI function */
return HalpGetPCIData(&BusHandler,
&BusHandler,
*(PPCI_SLOT_NUMBER)&SlotNumber,
Buffer,
Offset,
Length);
}
/* Invalid bus */
return 0;
}
/*
* @implemented
*/
ULONG
NTAPI
HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity)
{
/* Call the system bus translator */
return HalpGetSystemInterruptVector(BusNumber,
BusInterruptLevel,
BusInterruptVector,
Irql,
Affinity);
}
/*
* @implemented
*/
ULONG
NTAPI
HalSetBusData(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length)
{
/* Call the extended function */
return HalSetBusDataByOffset(BusDataType,
BusNumber,
SlotNumber,
Buffer,
0,
Length);
}
/*
* @implemented
*/
ULONG
NTAPI
HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
BUS_HANDLER BusHandler;
/* Look as the bus type */
if (BusDataType == Cmos)
{
/* Call CMOS Function */
return HalpSetCmosData(0, SlotNumber, Buffer, Length);
}
else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized))
{
/* Setup fake PCI Bus handler */
RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
BusHandler.BusNumber = BusNumber;
/* Call PCI function */
return HalpSetPCIData(&BusHandler,
&BusHandler,
*(PPCI_SLOT_NUMBER)&SlotNumber,
Buffer,
Offset,
Length);
}
/* Invalid bus */
return 0;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress)
{
/* Look as the bus type */
if (InterfaceType == PCIBus)
{
/* Call the PCI registered function */
return HalPciTranslateBusAddress(PCIBus,
BusNumber,
BusAddress,
AddressSpace,
TranslatedAddress);
}
else
{
/* Translation is easy */
TranslatedAddress->QuadPart = BusAddress.QuadPart;
return TRUE;
}
}
/* EOF */

View file

@ -1,291 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/cmos.c
* PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood)
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
KSPIN_LOCK HalpSystemHardwareLock;
/* PRIVATE FUNCTIONS *********************************************************/
UCHAR
FORCEINLINE
HalpReadCmos(IN UCHAR Reg)
{
/* Select the register */
WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
/* Query the value */
return READ_PORT_UCHAR(CMOS_DATA_PORT);
}
VOID
FORCEINLINE
HalpWriteCmos(IN UCHAR Reg,
IN UCHAR Value)
{
/* Select the register */
WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
/* Write the value */
WRITE_PORT_UCHAR(CMOS_DATA_PORT, Value);
}
ULONG
NTAPI
HalpGetCmosData(IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length)
{
PUCHAR Ptr = (PUCHAR)Buffer;
ULONG Address = SlotNumber;
ULONG Len = Length;
/* FIXME: Acquire CMOS Lock */
/* Do nothing if we don't have a length */
if (!Length) return 0;
/* Check if this is simple CMOS */
if (!BusNumber)
{
/* Loop the buffer up to 0xFF */
while ((Len > 0) && (Address < 0x100))
{
/* Read the data */
*Ptr = HalpReadCmos((UCHAR)Address);
/* Update position and length */
Ptr++;
Address++;
Len--;
}
}
else if (BusNumber == 1)
{
/* Loop the buffer up to 0xFFFF */
while ((Len > 0) && (Address < 0x10000))
{
/* Write the data */
*Ptr = HalpReadCmos((UCHAR)Address);
/* Update position and length */
Ptr++;
Address++;
Len--;
}
}
/* FIXME: Release the CMOS Lock */
/* Return length read */
return Length - Len;
}
ULONG
NTAPI
HalpSetCmosData(IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length)
{
PUCHAR Ptr = (PUCHAR)Buffer;
ULONG Address = SlotNumber;
ULONG Len = Length;
/* FIXME: Acquire CMOS Lock */
/* Do nothing if we don't have a length */
if (!Length) return 0;
/* Check if this is simple CMOS */
if (!BusNumber)
{
/* Loop the buffer up to 0xFF */
while ((Len > 0) && (Address < 0x100))
{
/* Write the data */
HalpWriteCmos((UCHAR)Address, *Ptr);
/* Update position and length */
Ptr++;
Address++;
Len--;
}
}
else if (BusNumber == 1)
{
/* Loop the buffer up to 0xFFFF */
while ((Len > 0) && (Address < 0x10000))
{
/* Write the data */
HalpWriteCmos((UCHAR)Address, *Ptr);
/* Update position and length */
Ptr++;
Address++;
Len--;
}
}
/* FIXME: Release the CMOS Lock */
/* Return length read */
return Length - Len;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
ARC_STATUS
NTAPI
HalGetEnvironmentVariable(IN PCH Name,
IN USHORT ValueLength,
IN PCH Value)
{
UCHAR Val;
/* Only variable supported on x86 */
if (_stricmp(Name, "LastKnownGood")) return ENOENT;
/* FIXME: Acquire CMOS Lock */
/* Query the current value */
Val = HalpReadCmos(RTC_REGISTER_B) & 0x01;
/* FIXME: Release CMOS lock */
/* Check the flag */
if (Val)
{
/* Return false */
strncpy(Value, "FALSE", ValueLength);
}
else
{
/* Return true */
strncpy(Value, "TRUE", ValueLength);
}
/* Return success */
return ESUCCESS;
}
/*
* @implemented
*/
ARC_STATUS
NTAPI
HalSetEnvironmentVariable(IN PCH Name,
IN PCH Value)
{
UCHAR Val;
/* Only variable supported on x86 */
if (_stricmp(Name, "LastKnownGood")) return ENOMEM;
/* Check if this is true or false */
if (!_stricmp(Value, "TRUE"))
{
/* It's true, acquire CMOS lock (FIXME) */
/* Read the current value and add the flag */
Val = HalpReadCmos(RTC_REGISTER_B) | 1;
}
else if (!_stricmp(Value, "FALSE"))
{
/* It's false, acquire CMOS lock (FIXME) */
/* Read the current value and mask out the flag */
Val = HalpReadCmos(RTC_REGISTER_B) & ~1;
}
else
{
/* Fail */
return ENOMEM;
}
/* Write new value */
HalpWriteCmos(RTC_REGISTER_B, Val);
/* Release the lock and return success */
return ESUCCESS;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
HalQueryRealTimeClock(OUT PTIME_FIELDS Time)
{
/* FIXME: Acquire CMOS Lock */
/* Loop while update is in progress */
while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
/* Set the time data */
Time->Second = BCD_INT(HalpReadCmos(0));
Time->Minute = BCD_INT(HalpReadCmos(2));
Time->Hour = BCD_INT(HalpReadCmos(4));
Time->Weekday = BCD_INT(HalpReadCmos(6));
Time->Day = BCD_INT(HalpReadCmos(7));
Time->Month = BCD_INT(HalpReadCmos(8));
Time->Year = BCD_INT(HalpReadCmos(9));
Time->Milliseconds = 0;
/* FIXME: Check century byte */
/* Compensate for the century field */
Time->Year += (Time->Year > 80) ? 1900: 2000;
/* FIXME: Release CMOS Lock */
/* Always return TRUE */
return TRUE;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
HalSetRealTimeClock(IN PTIME_FIELDS Time)
{
/* FIXME: Acquire CMOS Lock */
/* Loop while update is in progress */
while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
/* Write time fields to CMOS RTC */
HalpWriteCmos(0, INT_BCD(Time->Second));
HalpWriteCmos(2, INT_BCD(Time->Minute));
HalpWriteCmos(4, INT_BCD(Time->Hour));
HalpWriteCmos(6, INT_BCD(Time->Weekday));
HalpWriteCmos(7, INT_BCD(Time->Day));
HalpWriteCmos(8, INT_BCD(Time->Month));
HalpWriteCmos(9, INT_BCD(Time->Year % 100));
/* FIXME: Set the century byte */
/* FIXME: Release the CMOS Lock */
/* Always return TRUE */
return TRUE;
}
/* EOF */

View file

@ -1,383 +0,0 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
*
* 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.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/display.c
* PURPOSE: Blue screen display
* PROGRAMMER: Eric Kohl
* UPDATE HISTORY:
* Created 08/10/99
*/
/*
* Portions of this code are from the XFree86 Project and available from the
* following license:
*
* Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
* NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the XFree86 Project shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the
* XFree86 Project.
*/
/* DISPLAY OWNERSHIP
*
* So, who owns the physical display and is allowed to write to it?
*
* In MS NT, upon boot HAL owns the display. Somewhere in the boot
* sequence (haven't figured out exactly where or by who), some
* component calls HalAcquireDisplayOwnership. From that moment on,
* the display is owned by that component and is switched to graphics
* mode. The display is not supposed to return to text mode, except
* in case of a bug check. The bug check will call HalDisplayString
* to output a string to the text screen. HAL will notice that it
* currently doesn't own the display and will re-take ownership, by
* calling the callback function passed to HalAcquireDisplayOwnership.
* After the bugcheck, execution is halted. So, under NT, the only
* possible sequence of display modes is text mode -> graphics mode ->
* text mode (the latter hopefully happening very infrequently).
*
* Things are a little bit different in the current state of ReactOS.
* We want to have a functional interactive text mode. We should be
* able to switch from text mode to graphics mode when a GUI app is
* started and switch back to text mode when it's finished. Then, when
* another GUI app is started, another switch to and from graphics mode
* is possible. Also, when the system bugchecks in graphics mode we want
* to switch back to text mode to show the registers and stack trace.
* Last but not least, HalDisplayString is used a lot more in ReactOS,
* e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
* is present.
* 3 Components are involved in ReactOS: HAL, BLUE.SYS and VIDEOPRT.SYS.
* As in NT, on boot HAL owns the display. When entering the text mode
* command interpreter, BLUE.SYS kicks in. It will write directly to the
* screen, more or less behind HALs back.
* When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
* This open call will end up in VIDEOPRT.SYS. That component will then
* take ownership of the display by calling HalAcquireDisplayOwnership.
* When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
* we want to give ownership of the display back to HAL. Using the
* standard exported HAL functions, that's a bit of a problem, because
* there is no function defined to do that. In NT, this is handled by
* HalDisplayString, but that solution isn't satisfactory in ReactOS,
* because HalDisplayString is (in some cases) also used to output debug
* messages. If we do it the NT way, the first debug message output while
* in graphics mode would switch the display back to text mode.
* So, instead, if HalDisplayString detects that HAL doesn't have ownership
* of the display, it doesn't do anything.
* To return ownership to HAL, a new function is exported,
* HalReleaseDisplayOwnership. This function is called by the DISPLAY
* device Close routine in VIDEOPRT.SYS. It is also called at the beginning
* of a bug check, so HalDisplayString is activated again.
* Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
* should also refrain from writing to the screen buffer. The text mode
* screen buffer might overlap the graphics mode screen buffer, so changing
* something in the text mode buffer might mess up the graphics screen. To
* allow BLUE.SYS to detect if HAL owns the display, another new function is
* exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
* check if it's allowed to touch the text mode buffer.
*
* In an ideal world, when HAL takes ownership of the display, it should set
* up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
* calls. Unfortunately, this will require HAL to setup a real-mode interrupt
* table etc. So, we chickened out of that by having the loader set up the
* display before switching to protected mode. If HAL is given back ownership
* after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
* since there is already support for them via the VideoPortInt10 routine.
*/
#include <hal.h>
#include <ppcboot.h>
#include <ppcdebug.h>
#define NDEBUG
#include <debug.h>
boot_infos_t PpcEarlybootInfo;
#define SCREEN_SYNCHRONIZATION
/* VARIABLES ****************************************************************/
static ULONG CursorX = 0; /* Cursor Position */
static ULONG CursorY = 0;
static ULONG SizeX = 80; /* Display size */
static ULONG SizeY = 25;
static BOOLEAN DisplayInitialized = FALSE;
static BOOLEAN HalOwnsDisplay = TRUE;
static ULONG GraphVideoBuffer = 0;
static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
extern UCHAR XboxFont8x16[];
extern void SetPhys( ULONG Addr, ULONG Data );
extern ULONG GetPhys( ULONG Addr );
extern void SetPhysByte( ULONG Addr, ULONG Data );
/* PRIVATE FUNCTIONS *********************************************************/
VOID FASTCALL
HalClearDisplay (UCHAR CharAttribute)
{
ULONG i;
ULONG deviceSize =
PpcEarlybootInfo.dispDeviceRowBytes *
PpcEarlybootInfo.dispDeviceRect[3];
for(i = 0; i < deviceSize; i += sizeof(int) )
SetPhys(GraphVideoBuffer + i, CharAttribute);
CursorX = 0;
CursorY = 0;
}
/* STATIC FUNCTIONS *********************************************************/
VOID STATIC
HalScrollDisplay (VOID)
{
ULONG i, deviceSize =
PpcEarlybootInfo.dispDeviceRowBytes *
PpcEarlybootInfo.dispDeviceRect[3];
ULONG Dest = (ULONG)GraphVideoBuffer,
Src = (ULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes));
ULONG End = (ULONG)
GraphVideoBuffer +
(PpcEarlybootInfo.dispDeviceRowBytes *
(PpcEarlybootInfo.dispDeviceRect[3]-16));
while( Src < End )
{
SetPhys((ULONG)Dest, GetPhys(Src));
Src += 4; Dest += 4;
}
/* Clear the bottom row */
for(i = End; i < deviceSize; i += sizeof(int) )
SetPhys(GraphVideoBuffer + i, 1);
}
VOID STATIC FASTCALL
HalPutCharacter (CHAR Character)
{
WRITE_PORT_UCHAR((PVOID)0x3f8, Character);
#if 0
int i,j,k;
ULONG Dest =
(GraphVideoBuffer +
(16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) +
(8 * (PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)), RowDest;
UCHAR ByteToPlace;
for( i = 0; i < 16; i++ ) {
RowDest = Dest;
for( j = 0; j < 8; j++ ) {
ByteToPlace = ((128 >> j) & (XboxFont8x16[(16 * Character) + i])) ? 0xff : 1;
for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++, RowDest++ ) {
SetPhysByte(RowDest, ByteToPlace);
}
}
Dest += PpcEarlybootInfo.dispDeviceRowBytes;
}
#endif
}
/* PRIVATE FUNCTIONS ********************************************************/
VOID FASTCALL
HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
/*
* FUNCTION: Initialize the display
* ARGUMENTS:
* InitParameters = Parameters setup by the boot loader
*/
{
if (! DisplayInitialized)
{
boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra;
GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase;
memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(*XBootInfo));
/* Set cursor position */
CursorX = 0;
CursorY = 0;
SizeX = XBootInfo->dispDeviceRowBytes / XBootInfo->dispDeviceDepth;
SizeY = XBootInfo->dispDeviceRect[3] / 16;
HalClearDisplay(1);
DisplayInitialized = TRUE;
}
}
/* PUBLIC FUNCTIONS *********************************************************/
VOID NTAPI
HalReleaseDisplayOwnership(VOID)
/*
* FUNCTION: Release ownership of display back to HAL
*/
{
if (HalResetDisplayParameters == NULL)
return;
if (HalOwnsDisplay != FALSE)
return;
HalOwnsDisplay = TRUE;
HalClearDisplay(0);
}
VOID NTAPI
HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
/*
* FUNCTION:
* ARGUMENTS:
* ResetDisplayParameters = Pointer to a driver specific
* reset routine.
*/
{
HalOwnsDisplay = FALSE;
HalResetDisplayParameters = ResetDisplayParameters;
}
VOID NTAPI
HalDisplayString(IN PCH String)
/*
* FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
* already and displays a string
* ARGUMENT:
* string = ASCII string to display
* NOTE: Use with care because there is no support for returning from BSOD
* mode
*/
{
PCH pch;
//static KSPIN_LOCK Lock;
KIRQL OldIrql;
BOOLEAN InterruptsEnabled = __readmsr();
/* See comment at top of file */
if (! HalOwnsDisplay || ! DisplayInitialized)
{
return;
}
pch = String;
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//KiAcquireSpinLock(&Lock);
_disable();
while (*pch != 0)
{
if (*pch == '\n')
{
CursorY++;
CursorX = 0;
}
else if (*pch == '\b')
{
if (CursorX > 0)
{
CursorX--;
}
}
else if (*pch != '\r')
{
HalPutCharacter (*pch);
CursorX++;
if (CursorX >= SizeX)
{
CursorY++;
CursorX = 0;
}
}
if (CursorY >= SizeY)
{
HalScrollDisplay ();
CursorY = SizeY - 1;
}
pch++;
}
__writemsr(InterruptsEnabled);
//KiReleaseSpinLock(&Lock);
KeLowerIrql(OldIrql);
}
VOID NTAPI
HalQueryDisplayParameters(OUT PULONG DispSizeX,
OUT PULONG DispSizeY,
OUT PULONG CursorPosX,
OUT PULONG CursorPosY)
{
if (DispSizeX)
*DispSizeX = SizeX;
if (DispSizeY)
*DispSizeY = SizeY;
if (CursorPosX)
*CursorPosX = CursorX;
if (CursorPosY)
*CursorPosY = CursorY;
}
VOID NTAPI
HalSetDisplayParameters(IN ULONG CursorPosX,
IN ULONG CursorPosY)
{
CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
}
BOOLEAN NTAPI
HalQueryDisplayOwnership(VOID)
{
return !HalOwnsDisplay;
}
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -1,74 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/drive.c
* PURPOSE: I/O HAL Routines for Disk Access
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
HalpAssignDriveLetters(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
IN PSTRING NtDeviceName,
OUT PUCHAR NtSystemPath,
OUT PSTRING NtSystemPathString)
{
/* Call the kernel */
IoAssignDriveLetters(LoaderBlock,
NtDeviceName,
NtSystemPath,
NtSystemPathString);
}
NTSTATUS
NTAPI
HalpReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
IN ULONG SectorSize,
IN BOOLEAN ReturnRecognizedPartitions,
IN OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
{
/* Call the kernel */
return IoReadPartitionTable(DeviceObject,
SectorSize,
ReturnRecognizedPartitions,
PartitionBuffer);
}
NTSTATUS
NTAPI
HalpWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
IN ULONG SectorSize,
IN ULONG SectorsPerTrack,
IN ULONG NumberOfHeads,
IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
{
/* Call the kernel */
return IoWritePartitionTable(DeviceObject,
SectorSize,
SectorsPerTrack,
NumberOfHeads,
PartitionBuffer);
}
NTSTATUS
NTAPI
HalpSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
IN ULONG SectorSize,
IN ULONG PartitionNumber,
IN ULONG PartitionType)
{
/* Call the kernel */
return IoSetPartitionInformation(DeviceObject,
SectorSize,
PartitionNumber,
PartitionType);
}
/* EOF */

View file

@ -1,22 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/enum.c
* PURPOSE: Motherboard device enumerator
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* Created 01/05/2001
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
VOID
HalpStartEnumerator (VOID)
{
}
/* EOF */

View file

@ -1,100 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS HAL
* FILE: hal/halppc/generic/fmutex.c
* PURPOSE: Deprecated HAL Fast Mutex
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/*
* NOTE: Even HAL itself has #defines to use the Exi* APIs inside NTOSKRNL.
* These are only exported here for compatibility with really old
* drivers. Also note that in theory, these can be made much faster
* by using assembly and inlining all the operations, including
* raising and lowering irql.
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
#undef ExAcquireFastMutex
#undef ExReleaseFastMutex
/* FUNCTIONS *****************************************************************/
VOID
FASTCALL
ExAcquireFastMutex(PFAST_MUTEX FastMutex)
{
KIRQL OldIrql;
/* Raise IRQL to APC */
KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Decrease the count */
if (InterlockedDecrement(&FastMutex->Count))
{
/* Someone is still holding it, use slow path */
FastMutex->Contention++;
KeWaitForSingleObject(&FastMutex->Event,
WrExecutive,
KernelMode,
FALSE,
NULL);
}
/* Set the owner and IRQL */
FastMutex->Owner = KeGetCurrentThread();
FastMutex->OldIrql = OldIrql;
}
VOID
FASTCALL
ExReleaseFastMutex(PFAST_MUTEX FastMutex)
{
KIRQL OldIrql;
/* Erase the owner */
FastMutex->Owner = (PVOID)1;
OldIrql = FastMutex->OldIrql;
/* Increase the count */
if (InterlockedIncrement(&FastMutex->Count) <= 0)
{
/* Someone was waiting for it, signal the waiter */
KeSetEventBoostPriority(&FastMutex->Event, IO_NO_INCREMENT);
}
/* Lower IRQL back */
KeLowerIrql(OldIrql);
}
BOOLEAN
FASTCALL
ExiTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
{
KIRQL OldIrql;
/* Raise to APC_LEVEL */
KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Check if we can quickly acquire it */
if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
{
/* We have, set us as owners */
FastMutex->Owner = KeGetCurrentThread();
FastMutex->OldIrql = OldIrql;
return TRUE;
}
else
{
/* Acquire attempt failed */
KeLowerIrql(OldIrql);
return FALSE;
}
}
/* EOF */

View file

@ -1,277 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: Xbox HAL
* FILE: hal/halppc/generic/font.c
* PURPOSE: Font glyphs
* PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
* UPDATE HISTORY:
* Created 2004/12/02
*
* Note: Converted from the XFree vga.bdf font
*/
#define NDEBUG
#include <debug.h>
unsigned char XboxFont8x16[256 * 16] =
{
0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* 0x00 */
0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xa5,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* 0x01 */
0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xdb,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* 0x02 */
0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, /* 0x03 */
0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x04 */
0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x05 */
0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x06 */
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x07 */
0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x08 */
0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, /* 0x09 */
0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, /* 0x0a */
0x00,0x00,0x1e,0x06,0x0e,0x1a,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* 0x0b */
0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0c */
0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, /* 0x0d */
0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, /* 0x0e */
0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0f */
0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, /* 0x10 */
0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* 0x11 */
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, /* 0x12 */
0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, /* 0x13 */
0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, /* 0x14 */
0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, /* 0x15 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, /* 0x16 */
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0x17 */
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x18 */
0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0x19 */
0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1a */
0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1b */
0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1c */
0x00,0x00,0x00,0x00,0x00,0x28,0x6c,0xfe,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1d */
0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x1e */
0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x1f */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */
0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ! */
0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* " */
0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, /* # */
0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, /* $ */
0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, /* % */
0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* & */
0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ' */
0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, /* ( */
0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, /* ) */
0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, /* * */
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* + */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, /* , */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* . */
0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, /* / */
0x00,0x00,0x38,0x6c,0xc6,0xc6,0xd6,0xd6,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0 */
0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, /* 1 */
0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 2 */
0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 3 */
0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, /* 4 */
0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 5 */
0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 6 */
0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, /* 7 */
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 8 */
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, /* 9 */
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* : */
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, /* ; */
0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, /* < */
0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* = */
0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, /* > */
0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ? */
0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* @ */
0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* A */
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, /* B */
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, /* C */
0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, /* D */
0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* E */
0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* F */
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, /* G */
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* H */
0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* I */
0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* J */
0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* K */
0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* L */
0x00,0x00,0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* M */
0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* N */
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* O */
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* P */
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, /* Q */
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* R */
0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* S */
0x00,0x00,0x7e,0x7e,0x5a,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* T */
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* U */
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x10,0x00,0x00,0x00,0x00, /* V */
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0xee,0x6c,0x00,0x00,0x00,0x00, /* W */
0x00,0x00,0xc6,0xc6,0x6c,0x7c,0x38,0x38,0x7c,0x6c,0xc6,0xc6,0x00,0x00,0x00,0x00, /* X */
0x00,0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* Y */
0x00,0x00,0xfe,0xc6,0x86,0x0c,0x18,0x30,0x60,0xc2,0xc6,0xfe,0x00,0x00,0x00,0x00, /* Z */
0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, /* [ */
0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* \ */
0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, /* ] */
0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, /* _ */
0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ` */
0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* a */
0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, /* b */
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* c */
0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* d */
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* e */
0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* f */
0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, /* g */
0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* h */
0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* i */
0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, /* j */
0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, /* k */
0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* l */
0x00,0x00,0x00,0x00,0x00,0xec,0xfe,0xd6,0xd6,0xd6,0xd6,0xc6,0x00,0x00,0x00,0x00, /* m */
0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* n */
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* o */
0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, /* p */
0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, /* q */
0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* r */
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, /* s */
0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, /* t */
0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* u */
0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, /* v */
0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0x6c,0x00,0x00,0x00,0x00, /* w */
0x00,0x00,0x00,0x00,0x00,0xc6,0x6c,0x38,0x38,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00, /* x */
0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, /* y */
0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* z */
0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, /* { */
0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* | */
0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /* } */
0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ~ */
0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x7f */
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, /* 0x80 */
0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x81 */
0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x82 */
0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x83 */
0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x84 */
0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x85 */
0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x86 */
0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, /* 0x87 */
0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x88 */
0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x89 */
0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x8a */
0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8b */
0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8c */
0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8d */
0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8e */
0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8f */
0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, /* 0x90 */
0x00,0x00,0x00,0x00,0x00,0xcc,0x76,0x36,0x7e,0xd8,0xd8,0x6e,0x00,0x00,0x00,0x00, /* 0x91 */
0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, /* 0x92 */
0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x93 */
0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x94 */
0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x95 */
0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x96 */
0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x97 */
0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, /* 0x98 */
0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x99 */
0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x9a */
0x00,0x18,0x18,0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9b */
0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, /* 0x9c */
0x00,0x00,0x66,0x66,0x3c,0x18,0x7e,0x18,0x7e,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9d */
0x00,0xf8,0xcc,0xcc,0xf8,0xc4,0xcc,0xde,0xcc,0xcc,0xcc,0xc6,0x00,0x00,0x00,0x00, /* 0x9e */
0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, /* 0x9f */
0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa0 */
0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0xa1 */
0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa2 */
0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa3 */
0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* 0xa4 */
0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xa5 */
0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa6 */
0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa7 */
0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa8 */
0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, /* 0xa9 */
0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, /* 0xaa */
0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xdc,0x86,0x0c,0x18,0x3e,0x00,0x00, /* 0xab */
0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x9e,0x3e,0x06,0x06,0x00,0x00, /* 0xac */
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0xad */
0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xae */
0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xaf */
0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, /* 0xb0 */
0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, /* 0xb1 */
0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, /* 0xb2 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb3 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb4 */
0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb5 */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb6 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb7 */
0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb8 */
0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb9 */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xba */
0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xbb */
0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbc */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbd */
0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbe */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xbf */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc0 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc1 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc2 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc3 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc4 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc5 */
0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc6 */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc7 */
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc8 */
0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc9 */
0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xca */
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcb */
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcc */
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcd */
0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xce */
0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcf */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd0 */
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd1 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd2 */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd3 */
0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd4 */
0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd5 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd6 */
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd7 */
0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd8 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd9 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xda */
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdb */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdc */
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, /* 0xdd */
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, /* 0xde */
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdf */
0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, /* 0xe0 */
0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, /* 0xe1 */
0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, /* 0xe2 */
0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, /* 0xe3 */
0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 0xe4 */
0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xe5 */
0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, /* 0xe6 */
0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0xe7 */
0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0xe8 */
0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0xe9 */
0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, /* 0xea */
0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, /* 0xeb */
0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xec */
0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, /* 0xed */
0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, /* 0xee */
0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xef */
0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0xf0 */
0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, /* 0xf1 */
0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf2 */
0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf3 */
0x00,0x00,0x0e,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xf4 */
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xf5 */
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 0xf6 */
0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf7 */
0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf8 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf9 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfa */
0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, /* 0xfb */
0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfc */
0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfd */
0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, /* 0xfe */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 0xff */
};
/* EOF */

View file

@ -1,158 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/halinit.c
* PURPOSE: HAL Entrypoint and Initialization
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
HALP_HOOKS HalpHooks;
BOOLEAN HalpPciLockSettings;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR CommandLine;
/* Make sure we have a loader block and command line */
if ((LoaderBlock) && (LoaderBlock->LoadOptions))
{
/* Read the command line */
CommandLine = LoaderBlock->LoadOptions;
/* Check if PCI is locked */
if (strstr(CommandLine, "PCILOCK")) HalpPciLockSettings = TRUE;
/* Check for initial breakpoint */
if (strstr(CommandLine, "BREAK")) DbgBreakPoint();
}
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
BOOLEAN
NTAPI
HalInitSystem(IN ULONG BootPhase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
KIRQL CurIrql;
PKPRCB Prcb = KeGetCurrentPrcb();
DbgPrint("Prcb: %x BuildType %x\n", Prcb, Prcb->BuildType);
/* Check the boot phase */
if (!BootPhase)
{
/* Phase 0... save bus type */
HalpBusType = LoaderBlock->u.I386.MachineType & 0xFF;
/* Get command-line parameters */
HalpGetParameters(LoaderBlock);
/* Checked HAL requires checked kernel */
#if DBG
if (!(Prcb->BuildType & PRCB_BUILD_DEBUG))
{
/* No match, bugcheck */
KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 1, 0);
}
#else
/* Release build requires release HAL */
if (Prcb->BuildType & PRCB_BUILD_DEBUG)
{
/* No match, bugcheck */
KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
}
#endif
#ifdef CONFIG_SMP
/* SMP HAL requires SMP kernel */
if (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR)
{
/* No match, bugcheck */
KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
}
#endif
/* Validate the PRCB */
if (Prcb->MajorVersion != PRCB_MAJOR_VERSION)
{
/* Validation failed, bugcheck */
KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, 1, 0);
}
/* Initialize the PICs */
HalpInitPICs();
/* Force initial PIC state */
KeRaiseIrql(KeGetCurrentIrql(), &CurIrql);
/* Initialize the clock */
HalpInitializeClock();
/* Setup busy waiting */
//HalpCalibrateStallExecution();
/* Fill out the dispatch tables */
HalQuerySystemInformation = HaliQuerySystemInformation;
HalSetSystemInformation = HaliSetSystemInformation;
HalInitPnpDriver = NULL; // FIXME: TODO
HalGetDmaAdapter = HalpGetDmaAdapter;
HalGetInterruptTranslator = NULL; // FIXME: TODO
/* Initialize the hardware lock (CMOS) */
KeInitializeSpinLock(&HalpSystemHardwareLock);
}
else if (BootPhase == 1)
{
/* Initialize the default HAL stubs for bus handling functions */
HalpInitNonBusHandler();
#if 0
/* Enable the clock interrupt */
((PKIPCR)KeGetPcr())->IDT[0x30].ExtendedOffset =
(USHORT)(((ULONG_PTR)HalpClockInterrupt >> 16) & 0xFFFF);
((PKIPCR)KeGetPcr())->IDT[0x30].Offset =
(USHORT)((ULONG_PTR)HalpClockInterrupt);
#endif
HalEnableSystemInterrupt(0x30, CLOCK2_LEVEL, Latched);
/* Initialize DMA. NT does this in Phase 0 */
HalpInitDma();
}
/* All done, return */
return TRUE;
}
/*
* @unimplemented
*/
VOID
NTAPI
HalReportResourceUsage(VOID)
{
/* Initialize PCI bus. */
HalpInitializePciBus();
/* FIXME: This is done in ReactOS MP HAL only*/
//HaliReconfigurePciInterrupts();
/* FIXME: Report HAL Usage to kernel */
}
/* EOF */

View file

@ -1,452 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/irql.c
* PURPOSE: Implements IRQLs
* PROGRAMMER: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ******************************************************************/
/*
* FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
*/
typedef union
{
USHORT both;
struct
{
UCHAR master;
UCHAR slave;
};
}
PIC_MASK;
/*
* PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
* - At startup enable timer and cascade
*/
#if defined(__GNUC__)
static PIC_MASK pic_mask = {.both = 0xFFFA};
#else
static PIC_MASK pic_mask = { 0xFFFA };
#endif
/*
* PURPOSE: Mask for disabling of acknowledged interrupts
*/
#if defined(__GNUC__)
static PIC_MASK pic_mask_intr = {.both = 0x0000};
#else
static PIC_MASK pic_mask_intr = { 0 };
#endif
static ULONG HalpPendingInterruptCount[NR_IRQS];
#define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x)
#define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x)
#ifdef _MSC_VER
#define KiInterruptDispatch2(x, y)
#else
VOID NTAPI
KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
#endif
/* FUNCTIONS ****************************************************************/
#undef KeGetCurrentIrql
KIRQL NTAPI KeGetCurrentIrql (VOID)
/*
* PURPOSE: Returns the current irq level
* RETURNS: The current irq level
*/
{
return(KeGetPcr()->Irql);
}
VOID NTAPI HalpInitPICs(VOID)
{
memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
/* Initialization sequence */
WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
/* Start of hardware irqs (0x24) */
WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
/* 8259-1 is master */
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
/* 8259-2 is slave */
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
/* 8086 mode */
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
/* Enable interrupts */
WRITE_PORT_UCHAR((PUCHAR)0x21, 0xFF);
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xFF);
/* We can now enable interrupts */
_enable();
}
VOID HalpEndSystemInterrupt(KIRQL Irql)
/*
* FUNCTION: Enable all irqs with higher priority.
*/
{
const USHORT mask[] =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
};
/* Interrupts should be disable while enabling irqs of both pics */
_disable();
pic_mask_intr.both &= mask[Irql];
WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
/* restore ints */
_enable();
}
VOID
HalpExecuteIrqs(KIRQL NewIrql)
{
ULONG IrqLimit, i;
IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
/*
* For each irq if there have been any deferred interrupts then now
* dispatch them.
*/
for (i = 0; i < IrqLimit; i++)
{
if (HalpPendingInterruptCount[i] > 0)
{
KeGetPcr()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
while (HalpPendingInterruptCount[i] > 0)
{
/*
* For each deferred interrupt execute all the handlers at DIRQL.
*/
HalpPendingInterruptCount[i]--;
//HalpHardwareInt[i]();
}
//KeGetPcr()->Irql--;
//HalpEndSystemInterrupt(KeGetPcr()->Irql);
}
}
}
VOID
HalpLowerIrql(KIRQL NewIrql)
{
if (NewIrql >= PROFILE_LEVEL)
{
KeGetPcr()->Irql = NewIrql;
return;
}
HalpExecuteIrqs(NewIrql);
if (NewIrql >= DISPATCH_LEVEL)
{
KeGetPcr()->Irql = NewIrql;
return;
}
KeGetPcr()->Irql = DISPATCH_LEVEL;
if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST])
{
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
KiDispatchInterrupt();
}
KeGetPcr()->Irql = APC_LEVEL;
if (NewIrql == APC_LEVEL)
{
return;
}
if (KeGetCurrentThread() != NULL &&
KeGetCurrentThread()->ApcState.KernelApcPending)
{
KiDeliverApc(KernelMode, NULL, NULL);
}
KeGetPcr()->Irql = PASSIVE_LEVEL;
}
/**********************************************************************
* NAME EXPORTED
* KfLowerIrql
*
* DESCRIPTION
* Restores the irq level on the current processor
*
* ARGUMENTS
* NewIrql = Irql to lower to
*
* RETURN VALUE
* None
*
* NOTES
* Uses fastcall convention
*/
VOID FASTCALL
KfLowerIrql (KIRQL NewIrql)
{
DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
if (NewIrql > KeGetPcr()->Irql)
{
DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
__FILE__, __LINE__, NewIrql, KeGetPcr()->Irql);
KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
for(;;);
}
HalpLowerIrql(NewIrql);
}
/**********************************************************************
* NAME EXPORTED
* KfRaiseIrql
*
* DESCRIPTION
* Raises the hardware priority (irql)
*
* ARGUMENTS
* NewIrql = Irql to raise to
*
* RETURN VALUE
* previous irq level
*
* NOTES
* Uses fastcall convention
*/
KIRQL FASTCALL
KfRaiseIrql (KIRQL NewIrql)
{
KIRQL OldIrql;
DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
if (NewIrql < KeGetPcr()->Irql)
{
DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
__FILE__,__LINE__,KeGetPcr()->Irql,NewIrql);
KeBugCheck (IRQL_NOT_GREATER_OR_EQUAL);
for(;;);
}
OldIrql = KeGetPcr()->Irql;
KeGetPcr()->Irql = NewIrql;
return OldIrql;
}
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrqlToDpcLevel
*
* DESCRIPTION
* Raises the hardware priority (irql) to DISPATCH level
*
* ARGUMENTS
* None
*
* RETURN VALUE
* Previous irq level
*
* NOTES
* Calls KfRaiseIrql
*/
KIRQL NTAPI
KeRaiseIrqlToDpcLevel (VOID)
{
return KfRaiseIrql (DISPATCH_LEVEL);
}
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrqlToSynchLevel
*
* DESCRIPTION
* Raises the hardware priority (irql) to CLOCK2 level
*
* ARGUMENTS
* None
*
* RETURN VALUE
* Previous irq level
*
* NOTES
* Calls KfRaiseIrql
*/
KIRQL NTAPI
KeRaiseIrqlToSynchLevel (VOID)
{
return KfRaiseIrql (DISPATCH_LEVEL);
}
BOOLEAN NTAPI
HalBeginSystemInterrupt (KIRQL Irql,
ULONG Vector,
PKIRQL OldIrql)
{
ULONG irq;
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
{
return(FALSE);
}
irq = Vector - IRQ_BASE;
pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
if (irq < 8)
{
WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
}
else
{
WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
/* Send EOI to the PICs */
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
}
#if 0
if (KeGetPcr()->Irql >= Irql)
{
HalpPendingInterruptCount[irq]++;
return(FALSE);
}
#endif
*OldIrql = KeGetPcr()->Irql;
KeGetPcr()->Irql = Irql;
return(TRUE);
}
VOID NTAPI HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
/*
* FUNCTION: Finish a system interrupt and restore the specified irq level.
*/
{
HalpLowerIrql(Irql);
HalpEndSystemInterrupt(Irql);
}
VOID
NTAPI
HalDisableSystemInterrupt(
ULONG Vector,
KIRQL Irql)
{
ULONG irq;
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
{
ASSERT(FALSE);
return;
}
irq = Vector - IRQ_BASE;
pic_mask.both |= (1 << irq);
if (irq < 8)
{
WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
}
else
{
WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
}
return;
}
BOOLEAN
NTAPI
HalEnableSystemInterrupt(
ULONG Vector,
KIRQL Irql,
KINTERRUPT_MODE InterruptMode)
{
ULONG irq;
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
return FALSE;
irq = Vector - IRQ_BASE;
pic_mask.both &= ~(1 << irq);
if (irq < 8)
{
WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
}
else
{
WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
}
return TRUE;
}
VOID FASTCALL
HalRequestSoftwareInterrupt(
IN KIRQL Request)
{
switch (Request)
{
case APC_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE;
break;
case DISPATCH_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE;
break;
default:
DbgBreakPoint();
}
}
VOID FASTCALL
HalClearSoftwareInterrupt(
IN KIRQL Request)
{
switch (Request)
{
case APC_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE;
break;
case DISPATCH_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
break;
default:
DbgBreakPoint();
}
}
/* EOF */

View file

@ -1,74 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/isa.c
* PURPOSE: Interfaces to the ISA bus
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* 05/06/98: Created
*/
/* INCLUDES ***************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
BOOLEAN HalIsaProbe(VOID)
/*
* FUNCTION: Probes for an ISA bus
* RETURNS: True if detected
* NOTE: Since ISA is the default we are called last and always return
* true
*/
{
DbgPrint("Assuming ISA bus\n");
/*
* Probe for plug and play support
*/
return(TRUE);
}
BOOLEAN NTAPI
HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
ULONG BusNumber,
PHYSICAL_ADDRESS BusAddress,
PULONG AddressSpace,
PPHYSICAL_ADDRESS TranslatedAddress)
{
BOOLEAN Result;
Result = HalTranslateBusAddress(PCIBus,
BusNumber,
BusAddress,
AddressSpace,
TranslatedAddress);
if (Result != FALSE)
return Result;
Result = HalTranslateBusAddress(Internal,
BusNumber,
BusAddress,
AddressSpace,
TranslatedAddress);
return Result;
}
ULONG NTAPI
HalpGetIsaInterruptVector(PVOID BusHandler,
ULONG BusNumber,
ULONG BusInterruptLevel,
ULONG BusInterruptVector,
PKIRQL Irql,
PKAFFINITY Affinity)
{
ULONG Vector = IRQ2VECTOR(BusInterruptVector);
*Irql = VECTOR2IRQL(Vector);
*Affinity = 0xFFFFFFFF;
return Vector;
}
/* EOF */

View file

@ -1,105 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/misc.c
* PURPOSE: Miscellanous Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
HalpCheckPowerButton(VOID)
{
/* Nothing to do on non-ACPI */
return;
}
PVOID
NTAPI
HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberPage)
{
/* Use kernel memory manager I/O map facilities */
return MmMapIoSpace(PhysicalAddress,
NumberPage << PAGE_SHIFT,
MmNonCached);
}
VOID
NTAPI
HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
IN ULONG NumberPages)
{
/* Use kernel memory manager I/O map facilities */
MmUnmapIoSpace(VirtualAddress, NumberPages << PAGE_SHIFT);
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
VOID
NTAPI
HalHandleNMI(IN PVOID NmiInfo)
{
UCHAR ucStatus;
/* Get the NMI Flag */
ucStatus = READ_PORT_UCHAR((PUCHAR)0x61);
/* Display NMI failure string */
HalDisplayString ("\r\n*** Hardware Malfunction\r\n\r\n");
HalDisplayString ("Call your hardware vendor for support\r\n\r\n");
/* Check for parity error */
if (ucStatus & 0x80)
{
/* Display message */
HalDisplayString ("NMI: Parity Check / Memory Parity Error\r\n");
}
/* Check for I/O failure */
if (ucStatus & 0x40)
{
/* Display message */
HalDisplayString ("NMI: Channel Check / IOCHK\r\n");
}
/* Halt the system */
HalDisplayString("\r\n*** The system has halted ***\r\n");
//KeEnterKernelDebugger();
}
/*
* @implemented
*/
UCHAR
FASTCALL
HalSystemVectorDispatchEntry(IN ULONG Vector,
OUT PKINTERRUPT_ROUTINE **FlatDispatch,
OUT PKINTERRUPT_ROUTINE *NoConnection)
{
/* Not implemented on x86 */
return FALSE;
}
/*
* @implemented
*/
VOID
NTAPI
KeFlushWriteBuffer(VOID)
{
/* Not implemented on x86 */
return;
}

View file

@ -1,778 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/pci.c
* PURPOSE: PCI Bus Support (Configuration Space, Resource Allocation)
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
BOOLEAN HalpPCIConfigInitialized;
ULONG HalpMinPciBus, HalpMaxPciBus;
KSPIN_LOCK HalpPCIConfigLock;
PCI_CONFIG_HANDLER PCIConfigHandler;
/* PCI Operation Matrix */
UCHAR PCIDeref[4][4] =
{
{0, 1, 2, 2}, // ULONG-aligned offset
{1, 1, 1, 1}, // UCHAR-aligned offset
{2, 1, 2, 2}, // USHORT-aligned offset
{1, 1, 1, 1} // UCHAR-aligned offset
};
/* Type 1 PCI Bus */
PCI_CONFIG_HANDLER PCIConfigHandlerType1 =
{
/* Synchronization */
(FncSync)HalpPCISynchronizeType1,
(FncReleaseSync)HalpPCIReleaseSynchronzationType1,
/* Read */
{
(FncConfigIO)HalpPCIReadUlongType1,
(FncConfigIO)HalpPCIReadUcharType1,
(FncConfigIO)HalpPCIReadUshortType1
},
/* Write */
{
(FncConfigIO)HalpPCIWriteUlongType1,
(FncConfigIO)HalpPCIWriteUcharType1,
(FncConfigIO)HalpPCIWriteUshortType1
}
};
/* Type 2 PCI Bus */
PCI_CONFIG_HANDLER PCIConfigHandlerType2 =
{
/* Synchronization */
(FncSync)HalpPCISynchronizeType2,
(FncReleaseSync)HalpPCIReleaseSynchronzationType2,
/* Read */
{
(FncConfigIO)HalpPCIReadUlongType2,
(FncConfigIO)HalpPCIReadUcharType2,
(FncConfigIO)HalpPCIReadUshortType2
},
/* Write */
{
(FncConfigIO)HalpPCIWriteUlongType2,
(FncConfigIO)HalpPCIWriteUcharType2,
(FncConfigIO)HalpPCIWriteUshortType2
}
};
PCIPBUSDATA HalpFakePciBusData =
{
{
PCI_DATA_TAG,
PCI_DATA_VERSION,
HalpReadPCIConfig,
HalpWritePCIConfig,
NULL,
NULL,
{{{0}}},
{0, 0, 0, 0}
},
{{0}},
32,
};
BUS_HANDLER HalpFakePciBusHandler =
{
1,
PCIBus,
PCIConfiguration,
0,
NULL,
NULL,
&HalpFakePciBusData,
0,
{0, 0, 0, 0},
HalpGetPCIData,
HalpSetPCIData,
NULL,
HalpAssignPCISlotResources,
NULL,
NULL
};
/* TYPE 1 FUNCTIONS **********************************************************/
VOID
NTAPI
HalpPCISynchronizeType1(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PKIRQL Irql,
IN PPCI_TYPE1_CFG_BITS PciCfg1)
{
/* Setup the PCI Configuration Register */
PciCfg1->u.AsULONG = 0;
PciCfg1->u.bits.BusNumber = BusHandler->BusNumber;
PciCfg1->u.bits.DeviceNumber = Slot.u.bits.DeviceNumber;
PciCfg1->u.bits.FunctionNumber = Slot.u.bits.FunctionNumber;
PciCfg1->u.bits.Enable = TRUE;
/* Acquire the lock */
KeRaiseIrql(HIGH_LEVEL, Irql);
KiAcquireSpinLock(&HalpPCIConfigLock);
}
VOID
NTAPI
HalpPCIReleaseSynchronzationType1(IN PBUS_HANDLER BusHandler,
IN KIRQL Irql)
{
PCI_TYPE1_CFG_BITS PciCfg1;
/* Clear the PCI Configuration Register */
PciCfg1.u.AsULONG = 0;
WRITE_PORT_ULONG(((PPCIPBUSDATA)BusHandler->BusData)->Config.Type1.Address,
PciCfg1.u.AsULONG);
/* Release the lock */
KiReleaseSpinLock(&HalpPCIConfigLock);
KeLowerIrql(Irql);
}
TYPE1_READ(HalpPCIReadUcharType1, UCHAR)
TYPE1_READ(HalpPCIReadUshortType1, USHORT)
TYPE1_READ(HalpPCIReadUlongType1, ULONG)
TYPE1_WRITE(HalpPCIWriteUcharType1, UCHAR)
TYPE1_WRITE(HalpPCIWriteUshortType1, USHORT)
TYPE1_WRITE(HalpPCIWriteUlongType1, ULONG)
/* TYPE 2 FUNCTIONS **********************************************************/
VOID
NTAPI
HalpPCISynchronizeType2(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PKIRQL Irql,
IN PPCI_TYPE2_ADDRESS_BITS PciCfg)
{
PCI_TYPE2_CSE_BITS PciCfg2Cse;
PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
/* Setup the configuration register */
PciCfg->u.AsUSHORT = 0;
PciCfg->u.bits.Agent = (USHORT)Slot.u.bits.DeviceNumber;
PciCfg->u.bits.AddressBase = (USHORT)BusData->Config.Type2.Base;
/* Acquire the lock */
KeRaiseIrql(HIGH_LEVEL, Irql);
KiAcquireSpinLock(&HalpPCIConfigLock);
/* Setup the CSE Register */
PciCfg2Cse.u.AsUCHAR = 0;
PciCfg2Cse.u.bits.Enable = TRUE;
PciCfg2Cse.u.bits.FunctionNumber = (UCHAR)Slot.u.bits.FunctionNumber;
PciCfg2Cse.u.bits.Key = -1;
/* Write the bus number and CSE */
WRITE_PORT_UCHAR(BusData->Config.Type2.Forward,
(UCHAR)BusHandler->BusNumber);
WRITE_PORT_UCHAR(BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
}
VOID
NTAPI
HalpPCIReleaseSynchronzationType2(IN PBUS_HANDLER BusHandler,
IN KIRQL Irql)
{
PCI_TYPE2_CSE_BITS PciCfg2Cse;
PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
/* Clear CSE and bus number */
PciCfg2Cse.u.AsUCHAR = 0;
WRITE_PORT_UCHAR(BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
WRITE_PORT_UCHAR(BusData->Config.Type2.Forward, 0);
/* Release the lock */
KiReleaseSpinLock(&HalpPCIConfigLock);
KeLowerIrql(Irql);
}
TYPE2_READ(HalpPCIReadUcharType2, UCHAR)
TYPE2_READ(HalpPCIReadUshortType2, USHORT)
TYPE2_READ(HalpPCIReadUlongType2, ULONG)
TYPE2_WRITE(HalpPCIWriteUcharType2, UCHAR)
TYPE2_WRITE(HalpPCIWriteUshortType2, USHORT)
TYPE2_WRITE(HalpPCIWriteUlongType2, ULONG)
/* PCI CONFIGURATION SPACE ***************************************************/
VOID
NTAPI
HalpPCIConfig(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PUCHAR Buffer,
IN ULONG Offset,
IN ULONG Length,
IN FncConfigIO *ConfigIO)
{
KIRQL OldIrql;
ULONG i;
UCHAR State[20];
/* Synchronize the operation */
PCIConfigHandler.Synchronize(BusHandler, Slot, &OldIrql, State);
/* Loop every increment */
while (Length)
{
/* Find out the type of read/write we need to do */
i = PCIDeref[Offset % sizeof(ULONG)][Length % sizeof(ULONG)];
/* Do the read/write and return the number of bytes */
i = ConfigIO[i]((PPCIPBUSDATA)BusHandler->BusData,
State,
Buffer,
Offset);
/* Increment the buffer position and offset, and decrease the length */
Offset += i;
Buffer += i;
Length -= i;
}
/* Release the lock and PCI bus */
PCIConfigHandler.ReleaseSynchronzation(BusHandler, OldIrql);
}
VOID
NTAPI
HalpReadPCIConfig(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
/* Validate the PCI Slot */
if (!HalpValidPCISlot(BusHandler, Slot))
{
/* Fill the buffer with invalid data */
RtlFillMemory(Buffer, Length, -1);
}
else
{
/* Send the request */
HalpPCIConfig(BusHandler,
Slot,
Buffer,
Offset,
Length,
PCIConfigHandler.ConfigRead);
}
}
VOID
NTAPI
HalpWritePCIConfig(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
/* Validate the PCI Slot */
if (HalpValidPCISlot(BusHandler, Slot))
{
/* Send the request */
HalpPCIConfig(BusHandler,
Slot,
Buffer,
Offset,
Length,
PCIConfigHandler.ConfigWrite);
}
}
BOOLEAN
NTAPI
HalpValidPCISlot(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot)
{
PCI_SLOT_NUMBER MultiSlot;
PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
UCHAR HeaderType;
ULONG Device;
/* Simple validation */
if (Slot.u.bits.Reserved) return FALSE;
if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) return FALSE;
/* Function 0 doesn't need checking */
if (!Slot.u.bits.FunctionNumber) return TRUE;
/* Functions 0+ need Multi-Function support, so check the slot */
Device = Slot.u.bits.DeviceNumber;
MultiSlot = Slot;
MultiSlot.u.bits.FunctionNumber = 0;
/* Send function 0 request to get the header back */
HalpReadPCIConfig(BusHandler,
MultiSlot,
&HeaderType,
FIELD_OFFSET(PCI_COMMON_CONFIG, HeaderType),
sizeof(UCHAR));
/* Now make sure the header is multi-function */
if (!(HeaderType & PCI_MULTIFUNCTION) || (HeaderType == 0xFF)) return FALSE;
return TRUE;
}
/* HAL PCI CALLBACKS *********************************************************/
ULONG
NTAPI
HalpGetPCIData(IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PCI_SLOT_NUMBER Slot,
IN PUCHAR Buffer,
IN ULONG Offset,
IN ULONG Length)
{
UCHAR PciBuffer[PCI_COMMON_HDR_LENGTH];
PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)PciBuffer;
ULONG Len = 0;
/* Normalize the length */
if (Length > sizeof(PCI_COMMON_CONFIG)) Length = sizeof(PCI_COMMON_CONFIG);
/* Check if this is a vendor-specific read */
if (Offset >= PCI_COMMON_HDR_LENGTH)
{
/* Read the header */
HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, sizeof(ULONG));
/* Make sure the vendor is valid */
if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
}
else
{
/* Read the entire header */
Len = PCI_COMMON_HDR_LENGTH;
HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, Len);
/* Validate the vendor ID */
if (PciConfig->VendorID == PCI_INVALID_VENDORID)
{
/* It's invalid, but we want to return this much */
PciConfig->VendorID = PCI_INVALID_VENDORID;
Len = sizeof(USHORT);
}
/* Now check if there's space left */
if (Len < Offset) return 0;
/* There is, so return what's after the offset and normalize */
Len -= Offset;
if (Len > Length) Len = Length;
/* Copy the data into the caller's buffer */
RtlMoveMemory(Buffer, PciBuffer + Offset, Len);
/* Update buffer and offset, decrement total length */
Offset += Len;
Buffer += Len;
Length -= Len;
}
/* Now we still have something to copy */
if (Length)
{
/* Check if it's vendor-specific data */
if (Offset >= PCI_COMMON_HDR_LENGTH)
{
/* Read it now */
HalpReadPCIConfig(BusHandler, Slot, Buffer, Offset, Length);
Len += Length;
}
}
/* Update the total length read */
return Len;
}
ULONG
NTAPI
HalpSetPCIData(IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PCI_SLOT_NUMBER Slot,
IN PUCHAR Buffer,
IN ULONG Offset,
IN ULONG Length)
{
UCHAR PciBuffer[PCI_COMMON_HDR_LENGTH];
PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)PciBuffer;
ULONG Len = 0;
/* Normalize the length */
if (Length > sizeof(PCI_COMMON_CONFIG)) Length = sizeof(PCI_COMMON_CONFIG);
/* Check if this is a vendor-specific read */
if (Offset >= PCI_COMMON_HDR_LENGTH)
{
/* Read the header */
HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, sizeof(ULONG));
/* Make sure the vendor is valid */
if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
}
else
{
/* Read the entire header and validate the vendor ID */
Len = PCI_COMMON_HDR_LENGTH;
HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, Len);
if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
/* Return what's after the offset and normalize */
Len -= Offset;
if (Len > Length) Len = Length;
/* Copy the specific caller data */
RtlMoveMemory(PciBuffer + Offset, Buffer, Len);
/* Write the actual configuration data */
HalpWritePCIConfig(BusHandler, Slot, PciBuffer + Offset, Offset, Len);
/* Update buffer and offset, decrement total length */
Offset += Len;
Buffer += Len;
Length -= Len;
}
/* Now we still have something to copy */
if (Length)
{
/* Check if it's vendor-specific data */
if (Offset >= PCI_COMMON_HDR_LENGTH)
{
/* Read it now */
HalpWritePCIConfig(BusHandler, Slot, Buffer, Offset, Length);
Len += Length;
}
}
/* Update the total length read */
return Len;
}
NTSTATUS
NTAPI
HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock,
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
{
DPRINT1("Unimplemented!\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
{
DPRINT1("Unimplemented!\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PUNICODE_STRING RegistryPath,
IN PUNICODE_STRING DriverClassName OPTIONAL,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
IN ULONG Slot,
IN OUT PCM_RESOURCE_LIST *pAllocatedResources)
{
KeBugCheck(0);
return STATUS_SUCCESS;
}
ULONG
NTAPI
HaliPciInterfaceReadConfig(IN PBUS_HANDLER RootBusHandler,
IN ULONG BusNumber,
IN PCI_SLOT_NUMBER SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
BUS_HANDLER BusHandler;
PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)Buffer;
/* Setup fake PCI Bus handler */
RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
BusHandler.BusNumber = BusNumber;
/* Read configuration data */
HalpReadPCIConfig(&BusHandler, SlotNumber, Buffer, Offset, Length);
/* Check if caller only wanted at least Vendor ID */
if (Length >= 2)
{
/* Validate it */
if (PciData->VendorID != PCI_INVALID_VENDORID)
{
/* Check if this is the new maximum bus number */
if (HalpMaxPciBus < BusHandler.BusNumber)
{
/* Set it */
HalpMaxPciBus = BusHandler.BusNumber;
}
}
}
/* Return length */
return Length;
}
PPCI_REGISTRY_INFO_INTERNAL
NTAPI
HalpQueryPciRegistryInfo(VOID)
{
WCHAR NameBuffer[8];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName, ConfigName, IdentName;
HANDLE KeyHandle, BusKeyHandle;
NTSTATUS Status;
UCHAR KeyBuffer[sizeof(PPCI_REGISTRY_INFO) + 100];
PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer;
ULONG ResultLength;
PWSTR Tag;
ULONG i;
PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PPCI_REGISTRY_INFO PciRegInfo;
PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
/* Setup the object attributes for the key */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\Description\\"
L"System\\MultiFunctionAdapter");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the key */
Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status)) return NULL;
/* Setup the receiving string */
KeyName.Buffer = NameBuffer;
KeyName.MaximumLength = sizeof(NameBuffer);
/* Setup the configuration and identifier key names */
RtlInitUnicodeString(&ConfigName, L"ConfigurationData");
RtlInitUnicodeString(&IdentName, L"Identifier");
/* Keep looping for each ID */
for (i = 0; TRUE; i++)
{
/* Setup the key name */
RtlIntegerToUnicodeString(i, 10, &KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
/* Open it */
Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
/* None left, fail */
ZwClose(KeyHandle);
return NULL;
}
/* Read the registry data */
Status = ZwQueryValueKey(BusKeyHandle,
&IdentName,
KeyValueFullInformation,
ValueInfo,
sizeof(KeyBuffer),
&ResultLength);
if (!NT_SUCCESS(Status))
{
/* Failed, try the next one */
ZwClose(BusKeyHandle);
continue;
}
/* Get the PCI Tag and validate it */
Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
if ((Tag[0] != L'P') ||
(Tag[1] != L'C') ||
(Tag[2] != L'I') ||
(Tag[3]))
{
/* Not a valid PCI entry, skip it */
ZwClose(BusKeyHandle);
continue;
}
/* Now read our PCI structure */
Status = ZwQueryValueKey(BusKeyHandle,
&ConfigName,
KeyValueFullInformation,
ValueInfo,
sizeof(KeyBuffer),
&ResultLength);
ZwClose(BusKeyHandle);
if (!NT_SUCCESS(Status)) continue;
/* We read it OK! Get the actual resource descriptors */
FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
((ULONG_PTR)FullDescriptor->
PartialResourceList.PartialDescriptors);
/* Check if this is our PCI Registry Information */
if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
{
/* Close the key */
ZwClose(KeyHandle);
/* FIXME: Check PnP\PCI\CardList */
/* Get the PCI information */
PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1);
/* Allocate the return structure */
PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PCI_REGISTRY_INFO_INTERNAL),
TAG_HAL);
if (!PciRegistryInfo) return NULL;
/* Fill it out */
PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism;
PciRegistryInfo->NoBuses = PciRegInfo->NoBuses;
PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision;
PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision;
PciRegistryInfo->ElementCount = 0;
}
}
}
VOID
NTAPI
HalpInitializePciStubs(VOID)
{
PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
UCHAR PciType;
PPCIPBUSDATA BusData = (PPCIPBUSDATA)HalpFakePciBusHandler.BusData;
ULONG i;
PCI_SLOT_NUMBER j;
ULONG VendorId = 0;
/* Query registry information */
PciRegistryInfo = HalpQueryPciRegistryInfo();
if (!PciRegistryInfo)
{
/* Assume type 1 */
PciType = 1;
}
else
{
/* Get the type and free the info structure */
PciType = PciRegistryInfo->HardwareMechanism & 0xF;
ExFreePool(PciRegistryInfo);
}
/* Initialize the PCI lock */
KeInitializeSpinLock(&HalpPCIConfigLock);
/* Check the type of PCI bus */
switch (PciType)
{
/* Type 1 PCI Bus */
case 1:
/* Copy the Type 1 handler data */
RtlCopyMemory(&PCIConfigHandler,
&PCIConfigHandlerType1,
sizeof(PCIConfigHandler));
/* Set correct I/O Ports */
BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT;
BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT;
break;
/* Type 2 PCI Bus */
case 2:
/* Copy the Type 1 handler data */
RtlCopyMemory(&PCIConfigHandler,
&PCIConfigHandlerType2,
sizeof (PCIConfigHandler));
/* Set correct I/O Ports */
BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT;
BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT;
BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE;
/* Only 16 devices supported, not 32 */
BusData->MaxDevice = 16;
break;
default:
/* Invalid type */
DbgPrint("HAL: Unnkown PCI type\n");
}
/* Loop all possible buses */
for (i = 0; i < 256; i++)
{
/* Loop all devices */
for (j.u.AsULONG = 0; j.u.AsULONG < 32; j.u.AsULONG++)
{
/* Query the interface */
if (HaliPciInterfaceReadConfig(NULL,
i,
j,
&VendorId,
0,
sizeof(ULONG)))
{
/* Validate the vendor ID */
if ((USHORT)VendorId != PCI_INVALID_VENDORID)
{
/* Set this as the maximum ID */
HalpMaxPciBus = i;
break;
}
}
}
}
/* We're done */
HalpPCIConfigInitialized = TRUE;
}
VOID
NTAPI
HalpInitializePciBus(VOID)
{
/* Initialize the stubs */
HalpInitializePciStubs();
/* FIXME: Initialize NMI Crash Flag */
}
/* EOF */

View file

@ -1,282 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/portio.c
* PURPOSE: Port I/O functions
* PROGRAMMER: Eric Kohl
* UPDATE HISTORY:
* Created 18/10/99
*/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
/*
* This file contains the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated
* to (a) handle it all in a way that makes gcc able to optimize it
* as well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*/
/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
* On the other hand, I'd like to be sure of a non-existent port:
* I feel a bit unsafe about using 0x80 (should be safe, though)
*
* Linus
*/
#if defined(__GNUC__)
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
#else
#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
#endif
#elif defined(_MSC_VER)
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
#else
#define __SLOW_DOWN_IO __asm out 0x80, al
#endif
#else
#error Unknown compiler for inline assembler
#endif
#ifdef REALLY_SLOW_IO
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
#else
#define SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
extern int GetPhysByte(int Addr);
extern void SetPhysByte(int Addr, int Val);
extern int GetPhysWord(int Addr);
extern void SetPhysWord(int Addr, int Val);
extern int GetPhys(int Addr);
extern void SetPhys(int Addr, int Val);
__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 GetPhysWord\n"
"GetPhysWord:\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 SetPhysWord\n"
"SetPhysWord:\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"
);
VOID NTAPI
READ_PORT_BUFFER_UCHAR (PUCHAR Port,
PUCHAR Buffer,
ULONG Count)
{
while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); }
}
VOID NTAPI
READ_PORT_BUFFER_USHORT (PUSHORT Port,
PUSHORT Buffer,
ULONG Count)
{
while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); }
}
VOID NTAPI
READ_PORT_BUFFER_ULONG (PULONG Port,
PULONG Buffer,
ULONG Count)
{
while(Count--) { *Buffer++ = GetPhys((ULONG)Port); }
}
UCHAR NTAPI
READ_PORT_UCHAR (PUCHAR Port)
{
return GetPhys((ULONG)Port);
}
USHORT NTAPI
READ_PORT_USHORT (PUSHORT Port)
{
return GetPhysWord((ULONG)Port);
}
ULONG NTAPI
READ_PORT_ULONG (PULONG Port)
{
return GetPhys((ULONG)Port);
}
VOID NTAPI
WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
PUCHAR Buffer,
ULONG Count)
{
while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); }
}
VOID NTAPI
WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
PUSHORT Buffer,
ULONG Count)
{
while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); }
}
VOID NTAPI
WRITE_PORT_BUFFER_ULONG (PULONG Port,
PULONG Buffer,
ULONG Count)
{
while(Count--) { SetPhys((ULONG)Port, *Buffer++); }
}
VOID NTAPI
WRITE_PORT_UCHAR (PUCHAR Port,
UCHAR Value)
{
SetPhysByte((ULONG)Port, Value);
}
VOID NTAPI
WRITE_PORT_USHORT (PUSHORT Port,
USHORT Value)
{
SetPhysWord((ULONG)Port, Value);
}
VOID NTAPI
WRITE_PORT_ULONG (PULONG Port,
ULONG Value)
{
SetPhys((ULONG)Port, Value);
}
/* EOF */

View file

@ -1,75 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/processor.c
* PURPOSE: Intel MultiProcessor specification support
* PROGRAMMER: David Welch (welch@cwcom.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: Parts adapted from linux SMP code
* UPDATE HISTORY:
* 22/05/1998 DW Created
* 12/04/2001 CSH Added MultiProcessor specification support
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
#define INITIAL_STALL_COUNT 0x10000
VOID NTAPI
HalInitializeProcessor(ULONG ProcessorNumber,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock);
KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT;
}
BOOLEAN NTAPI
HalAllProcessorsStarted (VOID)
{
DPRINT("HalAllProcessorsStarted()\n");
return TRUE;
}
NTHALAPI
BOOLEAN
NTAPI
HalStartNextProcessor(
IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
IN PKPROCESSOR_STATE ProcessorState
)
{
DPRINT("HalStartNextProcessor(0x%lx 0x%lx)\n", LoaderBlock, ProcessorState);
return TRUE;
}
/*
* @implemented
*/
VOID
NTAPI
HalProcessorIdle(VOID)
{
/* Enable interrupts and halt the processor */
_enable();
}
/*
* @implemented
*/
VOID
NTAPI
HalRequestIpi(ULONG Reserved)
{
/* Not implemented on NT */
__debugbreak();
}
/* EOF */

View file

@ -1,61 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/profil.c
* PURPOSE: System Profiling
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
/*
* @unimplemented
*/
VOID
NTAPI
HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UNIMPLEMENTED;
return;
}
/*
* @unimplemented
*/
VOID
NTAPI
HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UNIMPLEMENTED;
return;
}
/*
* @unimplemented
*/
ULONG_PTR
NTAPI
HalSetProfileInterval(IN ULONG_PTR Interval)
{
UNIMPLEMENTED;
return Interval;
}
ULONG HalpDecrementerRoll = 0;
LARGE_INTEGER
KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFrequency)
{
LARGE_INTEGER Result;
/* for now */
if(PerformanceFrequency) PerformanceFrequency->QuadPart = 100000000;
Result.HighPart = HalpDecrementerRoll;
Result.LowPart = __rdtsc();
return Result;
}

View file

@ -1,40 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/generic/reboot.c
* PURPOSE: Reboot functions.
* PROGRAMMER: Eric Kohl
* UPDATE HISTORY:
* Created 11/10/99
*/
#include <hal.h>
#define NDEBUG
#include <debug.h>
typedef void (*void_fun)();
static VOID
HalReboot (VOID)
{
void_fun reset_vector = (void_fun)0xfff00100;
reset_vector();
}
VOID NTAPI
HalReturnToFirmware (
FIRMWARE_REENTRY Action
)
{
if (Action == HalHaltRoutine)
{
DbgPrint ("HalReturnToFirmware called!\n");
DbgBreakPoint ();
}
else if (Action == HalRebootRoutine)
{
HalReboot ();
}
}
/* EOF */

View file

@ -1,210 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/spinlock.c
* PURPOSE: Spinlock and Queued Spinlock Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
#undef KeAcquireSpinLock
#undef KeReleaseSpinLock
#undef KeLowerIrql
#undef KeRaiseIrql
KIRQL FASTCALL
KfRaiseIrql (KIRQL NewIrql);
VOID FASTCALL
KfLowerIrql (KIRQL NewIrql);
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
VOID
NTAPI
KeLowerIrql(KIRQL NewIrql)
{
/* Call the fastcall function */
KfLowerIrql(NewIrql);
}
/*
* @implemented
*/
NTKERNELAPI
KIRQL
NTAPI
KeRaiseIrql(KIRQL NewIrql,
PKIRQL OldIrql)
{
/* Call the fastcall function */
return *OldIrql = KfRaiseIrql(NewIrql);
}
/*
* @implemented
*/
VOID
NTAPI
KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
PKIRQL OldIrql)
{
/* Call the fastcall function */
*OldIrql = KfAcquireSpinLock(SpinLock);
}
/*
* @implemented
*/
KIRQL
FASTCALL
KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
{
/* Simply raise to dispatch */
return KfRaiseIrql(DISPATCH_LEVEL);
}
/*
* @implemented
*/
VOID
NTAPI
KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
KIRQL NewIrql)
{
/* Call the fastcall function */
KfReleaseSpinLock(SpinLock, NewIrql);
}
/*
* @implemented
*/
KIRQL
FASTCALL
KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
{
/* Simply raise to dispatch */
return KfRaiseIrql(DISPATCH_LEVEL);
}
/*
* @implemented
*/
VOID
FASTCALL
KfReleaseSpinLock(PKSPIN_LOCK SpinLock,
KIRQL OldIrql)
{
/* Simply lower IRQL back */
KfLowerIrql(OldIrql);
}
/*
* @implemented
*/
KIRQL
FASTCALL
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
{
/* Simply raise to dispatch */
return KfRaiseIrql(DISPATCH_LEVEL);
}
/*
* @implemented
*/
KIRQL
FASTCALL
KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
{
/* Simply raise to dispatch */
return KfRaiseIrql(DISPATCH_LEVEL);
}
/*
* @implemented
*/
VOID
FASTCALL
KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
/* Simply raise to dispatch */
LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
}
/*
* @implemented
*/
VOID
FASTCALL
KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
/* Simply raise to synch */
LockHandle->OldIrql = KfRaiseIrql(SYNCH_LEVEL);
}
/*
* @implemented
*/
VOID
FASTCALL
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
IN KIRQL OldIrql)
{
/* Simply lower IRQL back */
KfLowerIrql(OldIrql);
}
/*
* @implemented
*/
VOID
FASTCALL
KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
{
/* Simply lower IRQL back */
KfLowerIrql(LockHandle->OldIrql);
}
/*
* @implemented
*/
BOOLEAN
FASTCALL
KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
IN PKIRQL OldIrql)
{
/* Simply raise to dispatch */
*OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
/* Always return true on UP Machines */
return TRUE;
}
/*
* @implemented
*/
LOGICAL
FASTCALL
KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
OUT PKIRQL OldIrql)
{
/* Simply raise to dispatch */
*OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
/* Always return true on UP Machines */
return TRUE;
}
/* EOF */

View file

@ -1,40 +0,0 @@
/*
* PROJECT: ReactOS HA:
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/sysinfo.c
* PURPOSE: HAL Information Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
PUCHAR KdComPortInUse;
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
HaliQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
IN OUT PVOID Buffer,
OUT PULONG ReturnedLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
HaliSetSystemInformation(IN HAL_SET_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
IN OUT PVOID Buffer)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -1,138 +0,0 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halppc/generic/timer.c
* PURPOSE: HAL Timer Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
BOOLEAN HalpClockSetMSRate;
ULONG HalpCurrentTimeIncrement;
ULONG HalpCurrentRollOver;
ULONG HalpNextMSRate = 14;
ULONG HalpLargestClockMS = 15;
LARGE_INTEGER HalpRolloverTable[15] =
{
{{1197, 10032}},
{{2394, 20064}},
{{3591, 30096}},
{{4767, 39952}},
{{5964, 49984}},
{{7161, 60016}},
{{8358, 70048}},
{{9555, 80080}},
{{10731, 89936}},
{{11949, 100144}},
{{13125, 110000}},
{{14322, 120032}},
{{15519, 130064}},
{{16695, 139920}},
{{17892, 149952}}
};
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
HalpInitializeClock(VOID)
{
//PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Increment;
USHORT RollOver;
ULONG Flags = 0;
/* Get increment and rollover for the largest time clock ms possible */
Increment = HalpRolloverTable[HalpLargestClockMS - 1].HighPart;
RollOver = (USHORT)HalpRolloverTable[HalpLargestClockMS - 1].LowPart;
/* Set the maximum and minimum increment with the kernel */
HalpCurrentTimeIncrement = Increment;
KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart);
/* Disable interrupts */
Flags = __readmsr();
_disable();
/* Set the rollover */
__outbyte(TIMER_CONTROL_PORT, TIMER_SC0 | TIMER_BOTH | TIMER_MD2);
__outbyte(TIMER_DATA_PORT0, RollOver & 0xFF);
__outbyte(TIMER_DATA_PORT0, RollOver >> 8);
/* Restore interrupts if they were previously enabled */
__writemsr(Flags);
/* Save rollover and return */
HalpCurrentRollOver = RollOver;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
VOID
NTAPI
HalCalibratePerformanceCounter(IN volatile PLONG Count,
IN ULONGLONG NewCount)
{
ULONG Flags = 0;
/* Disable interrupts */
Flags = __readmsr();
_disable();
/* Do a decrement for this CPU */
_InterlockedDecrement(Count);
/* Wait for other CPUs */
while (*Count);
/* Restore interrupts if they were previously enabled */
__writemsr(Flags);
}
/*
* @implemented
*/
ULONG
NTAPI
HalSetTimeIncrement(IN ULONG Increment)
{
/* Round increment to ms */
Increment /= 10000;
/* Normalize between our minimum (1 ms) and maximum (variable) setting */
if (Increment > HalpLargestClockMS) Increment = HalpLargestClockMS;
if (Increment <= 0) Increment = 1;
/* Set the rate and tell HAL we want to change it */
HalpNextMSRate = Increment;
HalpClockSetMSRate = TRUE;
/* Return the increment */
return HalpRolloverTable[Increment - 1].HighPart;
}
VOID
NTHALAPI
KeStallExecutionProcessor(ULONG USec)
{
LARGE_INTEGER Freq, Start = KeQueryPerformanceCounter(&Freq), End;
LARGE_INTEGER Timebase, Remainder;
Timebase.QuadPart = 1000000;
Freq.QuadPart *= USec;
End = RtlLargeIntegerDivide(Freq, Timebase, &Remainder);
End.QuadPart += Start.QuadPart;
while(End.QuadPart > __rdtsc());
}
/* EOF */

View file

@ -1,208 +0,0 @@
/*
*
*/
#pragma once
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
/* APIC Register Address Map */
#define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
#define APIC_VER 0x0030 /* Local APIC Version Register (R) */
#define APIC_TPR 0x0080 /* Task Priority Register (R/W) */
#define APIC_APR 0x0090 /* Arbitration Priority Register (R) */
#define APIC_PPR 0x00A0 /* Processor Priority Register (R) */
#define APIC_EOI 0x00B0 /* EOI Register (W) */
#define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */
#define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
#define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
#define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */
#define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */
#define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */
#define APIC_ESR 0x0280 /* Error Status Register (R) */
#define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */
#define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */
#define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */
#define APIC_LVTTHMR 0x0330
#define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */
#define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */
#define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */
#define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */
#define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */
#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
#define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define APIC_VER_MASK 0xFF00FF
#define GET_APIC_VERSION(x) ((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_TPR_PRI 0xFF
#define APIC_TPR_INT 0xF0
#define APIC_TPR_SUB 0xF
#define APIC_TPR_MAX 0xFF /* Maximum priority */
#define APIC_TPR_MIN 0x20 /* Minimum priority */
#define APIC_LDR_MASK (0xFF << 24)
#define APIC_SIVR_ENABLE (0x1 << 8)
#define APIC_SIVR_FOCUS (0x1 << 9)
#define APIC_ESR_MASK (0xFE << 0) /* Error Mask */
#define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */
#define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */
#define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */
#define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */
#define APIC_ICR0_LEVEL (0x1 << 14) /* Level */
#define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */
#define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */
/* Delivery Modes */
#define APIC_DM_FIXED (0x0 << 8)
#define APIC_DM_LOWEST (0x1 << 8)
#define APIC_DM_SMI (0x2 << 8)
#define APIC_DM_REMRD (0x3 << 8)
#define APIC_DM_NMI (0x4 << 8)
#define APIC_DM_INIT (0x5 << 8)
#define APIC_DM_STARTUP (0x6 << 8)
#define APIC_DM_EXTINT (0x7 << 8)
#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
#define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8))
/* Destination Shorthand values */
#define APIC_ICR0_DESTS_FIELD (0x0 << 0)
#define APIC_ICR0_DESTS_SELF (0x1 << 18)
#define APIC_ICR0_DESTS_ALL (0x2 << 18)
#define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18)
#define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */
#define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */
#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
#define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24)
#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
#define SET_APIC_TIMER_BASE(x) ((x) << 18)
#define APIC_TIMER_BASE_CLKIN 0x0
#define APIC_TIMER_BASE_TMBASE 0x1
#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
#define APIC_LVT_MASKED (0x1 << 16) /* Mask */
#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
#define APIC_LVT3_DM (0x7 << 8)
#define APIC_LVT3_IIPP (0x1 << 13)
#define APIC_LVT3_TM (0x1 << 15)
#define APIC_LVT3_MASKED (0x1 << 16)
#define APIC_LVT3_OS (0x1 << 17)
#define APIC_TDCR_TMBASE (0x1 << 2)
#define APIC_TDCR_MASK 0x0F
#define APIC_TDCR_2 0x00
#define APIC_TDCR_4 0x01
#define APIC_TDCR_8 0x02
#define APIC_TDCR_16 0x03
#define APIC_TDCR_32 0x08
#define APIC_TDCR_64 0x09
#define APIC_TDCR_128 0x0A
#define APIC_TDCR_1 0x0B
#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
#define APIC_LVT_MASKED (0x1 << 16) /* Mask */
#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
#define APIC_LVT3_DM (0x7 << 8)
#define APIC_LVT3_IIPP (0x1 << 13)
#define APIC_LVT3_TM (0x1 << 15)
#define APIC_LVT3_MASKED (0x1 << 16)
#define APIC_LVT3_OS (0x1 << 17)
#define APIC_TDCR_TMBASE (0x1 << 2)
#define APIC_TDCR_MASK 0x0F
#define APIC_TDCR_2 0x00
#define APIC_TDCR_4 0x01
#define APIC_TDCR_8 0x02
#define APIC_TDCR_16 0x03
#define APIC_TDCR_32 0x08
#define APIC_TDCR_64 0x09
#define APIC_TDCR_128 0x0A
#define APIC_TDCR_1 0x0B
#define APIC_TARGET_SELF 0x100
#define APIC_TARGET_ALL 0x200
#define APIC_TARGET_ALL_BUT_SELF 0x300
#define APIC_INTEGRATED(version) (version & 0xF0)
typedef enum {
amPIC = 0, /* IMCR and PIC compatibility mode */
amVWIRE /* Virtual Wire compatibility mode */
} APIC_MODE;
#ifdef CONFIG_SMP
#define MAX_CPU 32
#else
#define MAX_CPU 1
#endif
/*
* Local APIC timer IRQ vector is on a different priority level,
* to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata.
*/
#define LOCAL_TIMER_VECTOR 0xEF
#define IPI_VECTOR 0xFB
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
/* CPU flags */
#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */
#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */
#define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */
typedef struct _CPU_INFO
{
UCHAR Flags; /* CPU flags */
UCHAR APICId; /* Local APIC ID */
UCHAR APICVersion; /* Local APIC version */
// UCHAR MaxLVT; /* Number of LVT registers */
ULONG BusSpeed; /* BUS speed */
ULONG CoreSpeed; /* Core speed */
UCHAR Padding[16-12]; /* Padding to 16-byte */
} CPU_INFO, *PCPU_INFO;
extern ULONG CPUCount; /* Total number of CPUs */
extern ULONG BootCPU; /* Bootstrap processor */
extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
/* Prototypes */
__inline VOID APICWrite(ULONG Offset, ULONG Value);
__inline ULONG APICRead(ULONG Offset);
VOID APICSendIPI(ULONG Target, ULONG Mode);
VOID APICSetup(VOID);
VOID HaliInitBSP(VOID);
VOID APICSyncArbIDs(VOID);
__inline VOID APICSendEOI(VOID);
VOID APICCalibrateTimer(ULONG CPU);
VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
static __inline ULONG ThisCPU(VOID)
{
return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
}
/* EOF */

View file

@ -1,291 +0,0 @@
#pragma once
//
// Helper Macros
//
#define PASTE2(x,y) x ## y
#define POINTER_TO_(x) PASTE2(P,x)
#define READ_FROM(x) PASTE2(READ_PORT_, x)
#define WRITE_TO(x) PASTE2(WRITE_PORT_, x)
//
// Declares a PCI Register Read/Write Routine
//
#define TYPE_DEFINE(x, y) \
ULONG \
NTAPI \
x( \
IN PPCIPBUSDATA BusData, \
IN y PciCfg, \
IN PUCHAR Buffer, \
IN ULONG Offset \
)
#define TYPE1_DEFINE(x) TYPE_DEFINE(x, PPCI_TYPE1_CFG_BITS);
#define TYPE2_DEFINE(x) TYPE_DEFINE(x, PPCI_TYPE2_ADDRESS_BITS);
//
// Defines a PCI Register Read/Write Type 1 Routine Prologue and Epilogue
//
#define TYPE1_START(x, y) \
TYPE_DEFINE(x, PPCI_TYPE1_CFG_BITS) \
{ \
ULONG i = Offset % sizeof(ULONG); \
PciCfg->u.bits.RegisterNumber = Offset / sizeof(ULONG); \
WRITE_PORT_ULONG(BusData->Config.Type1.Address, PciCfg->u.AsULONG);
#define TYPE1_END(y) \
return sizeof(y); }
#define TYPE2_END TYPE1_END
//
// PCI Register Read Type 1 Routine
//
#define TYPE1_READ(x, y) \
TYPE1_START(x, y) \
*((POINTER_TO_(y))Buffer) = \
READ_FROM(y)((POINTER_TO_(y))(BusData->Config.Type1.Data + i)); \
TYPE1_END(y)
//
// PCI Register Write Type 1 Routine
//
#define TYPE1_WRITE(x, y) \
TYPE1_START(x, y) \
WRITE_TO(y)((POINTER_TO_(y))(BusData->Config.Type1.Data + i), \
*((POINTER_TO_(y))Buffer)); \
TYPE1_END(y)
//
// Defines a PCI Register Read/Write Type 2 Routine Prologue and Epilogue
//
#define TYPE2_START(x, y) \
TYPE_DEFINE(x, PPCI_TYPE2_ADDRESS_BITS) \
{ \
PciCfg->u.bits.RegisterNumber = (USHORT)Offset;
//
// PCI Register Read Type 2 Routine
//
#define TYPE2_READ(x, y) \
TYPE2_START(x, y) \
*((POINTER_TO_(y))Buffer) = \
READ_FROM(y)((POINTER_TO_(y))(ULONG)PciCfg->u.AsUSHORT); \
TYPE2_END(y)
//
// PCI Register Write Type 2 Routine
//
#define TYPE2_WRITE(x, y) \
TYPE2_START(x, y) \
WRITE_TO(y)((POINTER_TO_(y))(ULONG)PciCfg->u.AsUSHORT, \
*((POINTER_TO_(y))Buffer)); \
TYPE2_END(y)
typedef struct _PCIPBUSDATA
{
PCIBUSDATA CommonData;
union
{
struct
{
PULONG Address;
ULONG Data;
} Type1;
struct
{
PUCHAR CSE;
PUCHAR Forward;
ULONG Base;
} Type2;
} Config;
ULONG MaxDevice;
} PCIPBUSDATA, *PPCIPBUSDATA;
typedef ULONG
(NTAPI *FncConfigIO)(
IN PPCIPBUSDATA BusData,
IN PVOID State,
IN PUCHAR Buffer,
IN ULONG Offset
);
typedef VOID
(NTAPI *FncSync)(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PKIRQL Irql,
IN PVOID State
);
typedef VOID
(NTAPI *FncReleaseSync)(
IN PBUS_HANDLER BusHandler,
IN KIRQL Irql
);
typedef struct _PCI_CONFIG_HANDLER
{
FncSync Synchronize;
FncReleaseSync ReleaseSynchronzation;
FncConfigIO ConfigRead[3];
FncConfigIO ConfigWrite[3];
} PCI_CONFIG_HANDLER, *PPCI_CONFIG_HANDLER;
typedef struct _PCI_REGISTRY_INFO_INTERNAL
{
UCHAR MajorRevision;
UCHAR MinorRevision;
UCHAR NoBuses;
UCHAR HardwareMechanism;
ULONG ElementCount;
PCI_CARD_DESCRIPTOR CardList[ANYSIZE_ARRAY];
} PCI_REGISTRY_INFO_INTERNAL, *PPCI_REGISTRY_INFO_INTERNAL;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
HalpPCISynchronizeType1(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PKIRQL Irql,
IN PPCI_TYPE1_CFG_BITS PciCfg
);
VOID
NTAPI
HalpPCIReleaseSynchronzationType1(
IN PBUS_HANDLER BusHandler,
IN KIRQL Irql
);
VOID
NTAPI
HalpPCISynchronizeType2(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PKIRQL Irql,
IN PPCI_TYPE2_ADDRESS_BITS PciCfg
);
VOID
NTAPI
HalpPCIReleaseSynchronzationType2(
IN PBUS_HANDLER BusHandler,
IN KIRQL Irql
);
TYPE1_DEFINE(HalpPCIReadUcharType1);
TYPE1_DEFINE(HalpPCIReadUshortType1);
TYPE1_DEFINE(HalpPCIReadUlongType1);
TYPE2_DEFINE(HalpPCIReadUcharType2);
TYPE2_DEFINE(HalpPCIReadUshortType2);
TYPE2_DEFINE(HalpPCIReadUlongType2);
TYPE1_DEFINE(HalpPCIWriteUcharType1);
TYPE1_DEFINE(HalpPCIWriteUshortType1);
TYPE1_DEFINE(HalpPCIWriteUlongType1);
TYPE2_DEFINE(HalpPCIWriteUcharType2);
TYPE2_DEFINE(HalpPCIWriteUshortType2);
TYPE2_DEFINE(HalpPCIWriteUlongType2);
BOOLEAN
NTAPI
HalpValidPCISlot(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot
);
VOID
NTAPI
HalpReadPCIConfig(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
);
VOID
NTAPI
HalpWritePCIConfig(
IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
);
ULONG
NTAPI
HalpGetSystemInterruptVector(
ULONG BusNumber,
ULONG BusInterruptLevel,
ULONG BusInterruptVector,
PKIRQL Irql,
PKAFFINITY Affinity
);
ULONG
NTAPI
HalpGetCmosData(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length
);
ULONG
NTAPI
HalpSetCmosData(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length
);
ULONG
NTAPI
HalpGetPCIData(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootBusHandler,
IN PCI_SLOT_NUMBER SlotNumber,
IN PUCHAR Buffer,
IN ULONG Offset,
IN ULONG Length
);
ULONG
NTAPI
HalpSetPCIData(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootBusHandler,
IN PCI_SLOT_NUMBER SlotNumber,
IN PUCHAR Buffer,
IN ULONG Offset,
IN ULONG Length
);
NTSTATUS
NTAPI
HalpAssignPCISlotResources(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PUNICODE_STRING RegistryPath,
IN PUNICODE_STRING DriverClassName OPTIONAL,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
IN ULONG Slot,
IN OUT PCM_RESOURCE_LIST *pAllocatedResources
);
VOID
NTAPI
HalpInitializePciBus(
VOID
);
extern ULONG HalpBusType;
extern BOOLEAN HalpPCIConfigInitialized;
extern BUS_HANDLER HalpFakePciBusHandler;
extern ULONG HalpMinPciBus, HalpMaxPciBus;
/* EOF */

View file

@ -1,49 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Hardware Abstraction Layer
* FILE: hal/halppc/include/hal.h
* PURPOSE: HAL Header
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
/* C Headers */
#include <stdio.h>
/* WDK HAL Compilation hack */
#include <excpt.h>
#include <ntdef.h>
#undef _NTHAL_
#undef DECLSPEC_IMPORT
#define DECLSPEC_IMPORT
#undef NTSYSAPI
#define NTSYSAPI __declspec(dllimport)
/* IFS/DDK/NDK Headers */
#include <ntifs.h>
#include <bugcodes.h>
#include <ntdddisk.h>
#include <arc/arc.h>
#include <iotypes.h>
#include <kefuncs.h>
#include <intrin.h>
#include <halfuncs.h>
#include <iofuncs.h>
#include <ldrtypes.h>
#include <obfuncs.h>
/* Internal kernel headers */
#include "internal/pci.h"
#include "internal/powerpc/intrin_i.h"
/* Internal HAL Headers */
#include "apic.h"
#include "bus.h"
#include "halirq.h"
#include "haldma.h"
#include "halp.h"
#include "mps.h"
#include "ioapic.h"
/* EOF */

View file

@ -1,380 +0,0 @@
#pragma once
/*
* DMA Page Register Structure
* 080 DMA RESERVED
* 081 DMA Page Register (channel 2)
* 082 DMA Page Register (channel 3)
* 083 DMA Page Register (channel 1)
* 084 DMA RESERVED
* 085 DMA RESERVED
* 086 DMA RESERVED
* 087 DMA Page Register (channel 0)
* 088 DMA RESERVED
* 089 PS/2-DMA Page Register (channel 6)
* 08A PS/2-DMA Page Register (channel 7)
* 08B PS/2-DMA Page Register (channel 5)
* 08C PS/2-DMA RESERVED
* 08D PS/2-DMA RESERVED
* 08E PS/2-DMA RESERVED
* 08F PS/2-DMA Page Register (channel 4)
*/
typedef struct _DMA_PAGE
{
UCHAR Reserved1;
UCHAR Channel2;
UCHAR Channel3;
UCHAR Channel1;
UCHAR Reserved2[3];
UCHAR Channel0;
UCHAR Reserved3;
UCHAR Channel6;
UCHAR Channel7;
UCHAR Channel5;
UCHAR Reserved4[3];
UCHAR Channel4;
} DMA_PAGE, *PDMA_PAGE;
/*
* DMA Channel Mask Register Structure
*
* MSB LSB
* x x x x x x x x
* ------------------- - -----
* | | | 00 - Select channel 0 mask bit
* | | \---- 01 - Select channel 1 mask bit
* | | 10 - Select channel 2 mask bit
* | | 11 - Select channel 3 mask bit
* | |
* | \---------- 0 - Clear mask bit
* | 1 - Set mask bit
* |
* \----------------------- xx - Reserved
*/
typedef struct _DMA_CHANNEL_MASK
{
UCHAR Channel: 2;
UCHAR SetMask: 1;
UCHAR Reserved: 5;
} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK;
/*
* DMA Mask Register Structure
*
* MSB LSB
* x x x x x x x x
* \---/ - - ----- -----
* | | | | | 00 - Channel 0 select
* | | | | \---- 01 - Channel 1 select
* | | | | 10 - Channel 2 select
* | | | | 11 - Channel 3 select
* | | | |
* | | | | 00 - Verify transfer
* | | | \------------ 01 - Write transfer
* | | | 10 - Read transfer
* | | |
* | | \-------------------- 0 - Autoinitialized
* | | 1 - Non-autoinitialized
* | |
* | \------------------------ 0 - Address increment select
* |
* | 00 - Demand mode
* \------------------------------ 01 - Single mode
* 10 - Block mode
* 11 - Cascade mode
*/
typedef union _DMA_MODE
{
struct
{
UCHAR Channel: 2;
UCHAR TransferType: 2;
UCHAR AutoInitialize: 1;
UCHAR AddressDecrement: 1;
UCHAR RequestMode: 2;
};
UCHAR Byte;
} DMA_MODE, *PDMA_MODE;
/*
* DMA Extended Mode Register Structure
*
* MSB LSB
* x x x x x x x x
* - - ----- ----- -----
* | | | | | 00 - Channel 0 select
* | | | | \---- 01 - Channel 1 select
* | | | | 10 - Channel 2 select
* | | | | 11 - Channel 3 select
* | | | |
* | | | | 00 - 8-bit I/O, by bytes
* | | | \------------ 01 - 16-bit I/O, by words, address shifted
* | | | 10 - 32-bit I/O, by bytes
* | | | 11 - 16-bit I/O, by bytes
* | | |
* | | \---------------------- 00 - Compatible
* | | 01 - Type A
* | | 10 - Type B
* | | 11 - Burst
* | |
* | \---------------------------- 0 - Terminal Count is Output
* |
* \---------------------------------0 - Disable Stop Register
* 1 - Enable Stop Register
*/
typedef union _DMA_EXTENDED_MODE
{
struct
{
UCHAR ChannelNumber: 2;
UCHAR TransferSize: 2;
UCHAR TimingMode: 2;
UCHAR TerminalCountIsOutput: 1;
UCHAR EnableStopRegister: 1;
};
UCHAR Byte;
} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE;
/* DMA Extended Mode Register Transfer Sizes */
#define B_8BITS 0
#define W_16BITS 1
#define B_32BITS 2
#define B_16BITS 3
/* DMA Extended Mode Register Timing */
#define COMPATIBLE_TIMING 0
#define TYPE_A_TIMING 1
#define TYPE_B_TIMING 2
#define BURST_TIMING 3
/* Channel Stop Registers for each Channel */
typedef struct _DMA_CHANNEL_STOP
{
UCHAR ChannelLow;
UCHAR ChannelMid;
UCHAR ChannelHigh;
UCHAR Reserved;
} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP;
/* Transfer Types */
#define VERIFY_TRANSFER 0x00
#define READ_TRANSFER 0x01
#define WRITE_TRANSFER 0x02
/* Request Modes */
#define DEMAND_REQUEST_MODE 0x00
#define SINGLE_REQUEST_MODE 0x01
#define BLOCK_REQUEST_MODE 0x02
#define CASCADE_REQUEST_MODE 0x03
#define DMA_SETMASK 4
#define DMA_CLEARMASK 0
#define DMA_READ 4
#define DMA_WRITE 8
#define DMA_SINGLE_TRANSFER 0x40
#define DMA_AUTO_INIT 0x10
typedef struct _DMA1_ADDRESS_COUNT
{
UCHAR DmaBaseAddress;
UCHAR DmaBaseCount;
} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT;
typedef struct _DMA2_ADDRESS_COUNT
{
UCHAR DmaBaseAddress;
UCHAR Reserved1;
UCHAR DmaBaseCount;
UCHAR Reserved2;
} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT;
typedef struct _DMA1_CONTROL
{
DMA1_ADDRESS_COUNT DmaAddressCount[4];
UCHAR DmaStatus;
UCHAR DmaRequest;
UCHAR SingleMask;
UCHAR Mode;
UCHAR ClearBytePointer;
UCHAR MasterClear;
UCHAR ClearMask;
UCHAR AllMask;
} DMA1_CONTROL, *PDMA1_CONTROL;
typedef struct _DMA2_CONTROL
{
DMA2_ADDRESS_COUNT DmaAddressCount[4];
UCHAR DmaStatus;
UCHAR Reserved1;
UCHAR DmaRequest;
UCHAR Reserved2;
UCHAR SingleMask;
UCHAR Reserved3;
UCHAR Mode;
UCHAR Reserved4;
UCHAR ClearBytePointer;
UCHAR Reserved5;
UCHAR MasterClear;
UCHAR Reserved6;
UCHAR ClearMask;
UCHAR Reserved7;
UCHAR AllMask;
UCHAR Reserved8;
} DMA2_CONTROL, *PDMA2_CONTROL;
/* This structure defines the I/O Map of the 82537 controller. */
typedef struct _EISA_CONTROL
{
/* DMA Controller 1 */
DMA1_CONTROL DmaController1; /* 00h-0Fh */
UCHAR Reserved1[16]; /* 0Fh-1Fh */
/* Interrupt Controller 1 (PIC) */
UCHAR Pic1Operation; /* 20h */
UCHAR Pic1Interrupt; /* 21h */
UCHAR Reserved2[30]; /* 22h-3Fh */
/* Timer */
UCHAR TimerCounter; /* 40h */
UCHAR TimerMemoryRefresh; /* 41h */
UCHAR Speaker; /* 42h */
UCHAR TimerOperation; /* 43h */
UCHAR TimerMisc; /* 44h */
UCHAR Reserved3[2]; /* 45-46h */
UCHAR TimerCounterControl; /* 47h */
UCHAR TimerFailSafeCounter; /* 48h */
UCHAR Reserved4; /* 49h */
UCHAR TimerCounter2; /* 4Ah */
UCHAR TimerOperation2; /* 4Bh */
UCHAR Reserved5[20]; /* 4Ch-5Fh */
/* NMI / Keyboard / RTC */
UCHAR Keyboard; /* 60h */
UCHAR NmiStatus; /* 61h */
UCHAR Reserved6[14]; /* 62h-6Fh */
UCHAR NmiEnable; /* 70h */
UCHAR Reserved7[15]; /* 71h-7Fh */
/* DMA Page Registers Controller 1 */
DMA_PAGE DmaController1Pages; /* 80h-8Fh */
UCHAR Reserved8[16]; /* 90h-9Fh */
/* Interrupt Controller 2 (PIC) */
UCHAR Pic2Operation; /* 0A0h */
UCHAR Pic2Interrupt; /* 0A1h */
UCHAR Reserved9[30]; /* 0A2h-0BFh */
/* DMA Controller 2 */
DMA1_CONTROL DmaController2; /* 0C0h-0CFh */
/* System Reserved Ports */
UCHAR SystemReserved[816]; /* 0D0h-3FFh */
/* Extended DMA Registers, Controller 1 */
UCHAR DmaHighByteCount1[8]; /* 400h-407h */
UCHAR Reserved10[2]; /* 408h-409h */
UCHAR DmaChainMode1; /* 40Ah */
UCHAR DmaExtendedMode1; /* 40Bh */
UCHAR DmaBufferControl; /* 40Ch */
UCHAR Reserved11[84]; /* 40Dh-460h */
UCHAR ExtendedNmiControl; /* 461h */
UCHAR NmiCommand; /* 462h */
UCHAR Reserved12; /* 463h */
UCHAR BusMaster; /* 464h */
UCHAR Reserved13[27]; /* 465h-47Fh */
/* DMA Page Registers Controller 2 */
DMA_PAGE DmaController2Pages; /* 480h-48Fh */
UCHAR Reserved14[48]; /* 490h-4BFh */
/* Extended DMA Registers, Controller 2 */
UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */
/* Edge/Level Control Registers */
UCHAR Pic1EdgeLevel; /* 4D0h */
UCHAR Pic2EdgeLevel; /* 4D1h */
UCHAR Reserved15[2]; /* 4D2h-4D3h */
/* Extended DMA Registers, Controller 2 */
UCHAR DmaChainMode2; /* 4D4h */
UCHAR Reserved16; /* 4D5h */
UCHAR DmaExtendedMode2; /* 4D6h */
UCHAR Reserved17[9]; /* 4D7h-4DFh */
/* DMA Stop Registers */
DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */
} EISA_CONTROL, *PEISA_CONTROL;
typedef struct _ROS_MAP_REGISTER_ENTRY
{
PVOID VirtualAddress;
PHYSICAL_ADDRESS PhysicalAddress;
ULONG Counter;
} ROS_MAP_REGISTER_ENTRY, *PROS_MAP_REGISTER_ENTRY;
typedef struct _ADAPTER_OBJECT {
/*
* New style DMA object definition. The fact that it is at the beginning
* of the ADAPTER_OBJECT structure allows us to easily implement the
* fallback implementation of IoGetDmaAdapter.
*/
DMA_ADAPTER DmaHeader;
/*
* For normal adapter objects pointer to master adapter that takes care
* of channel allocation. For master adapter set to NULL.
*/
struct _ADAPTER_OBJECT *MasterAdapter;
ULONG MapRegistersPerChannel;
PVOID AdapterBaseVa;
PROS_MAP_REGISTER_ENTRY MapRegisterBase;
ULONG NumberOfMapRegisters;
ULONG CommittedMapRegisters;
PWAIT_CONTEXT_BLOCK CurrentWcb;
KDEVICE_QUEUE ChannelWaitQueue;
PKDEVICE_QUEUE RegisterWaitQueue;
LIST_ENTRY AdapterQueue;
KSPIN_LOCK SpinLock;
PRTL_BITMAP MapRegisters;
PUCHAR PagePort;
UCHAR ChannelNumber;
UCHAR AdapterNumber;
USHORT DmaPortAddress;
DMA_MODE AdapterMode;
BOOLEAN NeedsMapRegisters;
BOOLEAN MasterDevice;
BOOLEAN Width16Bits;
BOOLEAN ScatterGather;
BOOLEAN IgnoreCount;
BOOLEAN Dma32BitAddresses;
BOOLEAN Dma64BitAddresses;
LIST_ENTRY AdapterList;
} ADAPTER_OBJECT;
typedef struct _GROW_WORK_ITEM {
WORK_QUEUE_ITEM WorkQueueItem;
PADAPTER_OBJECT AdapterObject;
ULONG NumberOfMapRegisters;
} GROW_WORK_ITEM, *PGROW_WORK_ITEM;
#define MAP_BASE_SW_SG 1
PADAPTER_OBJECT NTAPI
HalpDmaAllocateMasterAdapter(VOID);
PDMA_ADAPTER NTAPI
HalpGetDmaAdapter(
IN PVOID Context,
IN PDEVICE_DESCRIPTION DeviceDescription,
OUT PULONG NumberOfMapRegisters);
ULONG NTAPI
HalpDmaGetDmaAlignment(
PADAPTER_OBJECT AdapterObject);

View file

@ -1,29 +0,0 @@
#pragma once
#ifdef CONFIG_SMP
#define FIRST_DEVICE_VECTOR (0x30)
#define FIRST_SYSTEM_VECTOR (0xef)
#define IRQ_BASE FIRST_DEVICE_VECTOR
#define NR_IRQS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/*
* FIXME:
* This does not work if we have more than 24 IRQs (ie. more than one I/O APIC)
*/
#define VECTOR2IRQ(vector) (23 - (vector - IRQ_BASE) / 8)
#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector))
#define IRQ2VECTOR(irq) (((23 - (irq)) * 8) + FIRST_DEVICE_VECTOR)
#else
#define IRQ_BASE (0x30)
#define NR_IRQS (16)
#define VECTOR2IRQ(vector) ((vector) - IRQ_BASE)
#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector))
#define IRQ2VECTOR(irq) ((irq) + IRQ_BASE)
#endif

View file

@ -1,126 +0,0 @@
/*
*
*/
#pragma once
/* Temporary hack */
#define KPCR_BASE 0xFF000000
#define HAL_APC_REQUEST 0
#define HAL_DPC_REQUEST 1
/* CMOS Registers and Ports */
#define CMOS_CONTROL_PORT (PUCHAR)0x70
#define CMOS_DATA_PORT (PUCHAR)0x71
#define RTC_REGISTER_A 0x0A
#define RTC_REGISTER_B 0x0B
#define RTC_REG_A_UIP 0x80
#define RTC_REGISTER_CENTURY 0x32
/* Timer Registers and Ports */
#define TIMER_CONTROL_PORT 0x43
#define TIMER_DATA_PORT0 0x40
#define TIMER_SC0 0
#define TIMER_BOTH 0x30
#define TIMER_MD2 0x4
/* Conversion functions */
#define BCD_INT(bcd) \
(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
#define INT_BCD(int) \
(UCHAR)(((int / 10) << 4) + (int % 10))
/* adapter.c */
PADAPTER_OBJECT NTAPI HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
/* bus.c */
VOID NTAPI HalpInitNonBusHandler (VOID);
/* irql.c */
VOID NTAPI HalpInitPICs(VOID);
/* udelay.c */
VOID NTAPI HalpInitializeClock(VOID);
/* pci.c */
VOID HalpInitPciBus (VOID);
/* dma.c */
VOID HalpInitDma (VOID);
/* Non-generic initialization */
VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID HalpInitPhase1(VOID);
VOID NTAPI HalpClockInterrupt(VOID);
//
// KD Support
//
VOID
NTAPI
HalpCheckPowerButton(
VOID
);
VOID
NTAPI
HalpRegisterKdSupportFunctions(
VOID
);
NTSTATUS
NTAPI
HalpSetupPciDeviceForDebugging(
IN PVOID LoaderBlock,
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
);
NTSTATUS
NTAPI
HalpReleasePciDeviceForDebugging(
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
);
//
// Memory routines
//
PVOID
NTAPI
HalpMapPhysicalMemory64(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberPage
);
VOID
NTAPI
HalpUnmapVirtualAddress(
IN PVOID VirtualAddress,
IN ULONG NumberPages
);
/* sysinfo.c */
NTSTATUS
NTAPI
HaliQuerySystemInformation(
IN HAL_QUERY_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
IN OUT PVOID Buffer,
OUT PULONG ReturnedLength
);
NTSTATUS
NTAPI
HaliSetSystemInformation(
IN HAL_SET_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
IN OUT PVOID Buffer
);
typedef struct tagHALP_HOOKS
{
void (*InitPciBus)(ULONG BusNumber, PBUS_HANDLER BusHandler);
} HALP_HOOKS, *PHALP_HOOKS;
extern HALP_HOOKS HalpHooks;
extern KSPIN_LOCK HalpSystemHardwareLock;

View file

@ -1,97 +0,0 @@
/*
*
*/
#pragma once
/* I/O APIC Register Address Map */
#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */
#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */
#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */
#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */
#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */
#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit registers) (R/W) */
#define IOAPIC_ID_MASK (0xF << 24)
#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24)
#define SET_IOAPIC_ID(x) ((x) << 24)
#define IOAPIC_VER_MASK (0xFF)
#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection Entry */
#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16)
#define IOAPIC_ARB_MASK (0xF << 24)
#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24)
#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */
#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */
#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */
#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity */
#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */
#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */
#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */
#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical mode) */
#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical mode) */
#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */
#include <pshpack1.h>
typedef struct _IOAPIC_ROUTE_ENTRY {
ULONG vector : 8,
delivery_mode : 3, /* 000: FIXED
* 001: lowest priority
* 111: ExtINT
*/
dest_mode : 1, /* 0: physical, 1: logical */
delivery_status : 1,
polarity : 1,
irr : 1,
trigger : 1, /* 0: edge, 1: level */
mask : 1, /* 0: enabled, 1: disabled */
__reserved_2 : 15;
union {
struct {
ULONG __reserved_1 : 24,
physical_dest : 4,
__reserved_2 : 4;
} physical;
struct {
ULONG __reserved_1 : 24,
logical_dest : 8;
} logical;
} dest;
} IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
#include <poppack.h>
typedef struct _IOAPIC_INFO
{
ULONG ApicId; /* APIC ID */
ULONG ApicVersion; /* APIC version */
ULONG ApicAddress; /* APIC address */
ULONG EntryCount; /* Number of redirection entries */
} IOAPIC_INFO, *PIOAPIC_INFO;
#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */
extern ULONG IRQCount; /* Number of IRQs */
extern UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */
extern UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */
extern IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
extern ULONG IOAPICCount; /* Number of I/O APICs in the system */
extern ULONG APICMode; /* APIC mode at startup */
extern MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
VOID IOAPICSetupIrqs(VOID);
VOID IOAPICEnable(VOID);
VOID IOAPICSetupIds(VOID);
VOID IOAPICMaskIrq(ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Irq);
VOID HaliReconfigurePciInterrupts(VOID);
/* For debugging */
VOID IOAPICDump(VOID);
/* EOF */

View file

@ -1,200 +0,0 @@
#pragma once
/*
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one
* I/O APIC)
*/
#define IRQL2VECTOR(irql) (IRQ2VECTOR(PROFILE_LEVEL - (irql)))
#define IRQL2TPR(irql) ((irql) >= IPI_LEVEL ? IPI_VECTOR : ((irql) >= PROFILE_LEVEL ? LOCAL_TIMER_VECTOR : ((irql) > DISPATCH_LEVEL ? IRQL2VECTOR(irql) : 0)))
typedef struct _KIRQ_TRAPFRAME
{
ULONG Magic;
ULONG Gs;
ULONG Fs;
ULONG Es;
ULONG Ds;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Eip;
ULONG Cs;
ULONG Eflags;
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
#if 0
/* This values are defined in halirql.h */
#define FIRST_DEVICE_VECTOR 0x30
#define FIRST_SYSTEM_VECTOR 0xEF
#endif
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/* MP Floating Pointer Structure */
#define MPF_SIGNATURE (('_' << 24) | ('P' << 16) | ('M' << 8) | '_')
#include <pshpack1.h>
typedef struct _MP_FLOATING_POINTER
{
ULONG Signature; /* _MP_ */
ULONG Address; /* Physical Address Pointer (0 means no configuration table exist) */
UCHAR Length; /* Structure length in 16-byte paragraphs */
UCHAR Specification; /* Specification revision */
UCHAR Checksum; /* Checksum */
UCHAR Feature1; /* MP System Configuration Type */
UCHAR Feature2; /* Bit 7 set for IMCR|PIC */
UCHAR Feature3; /* Unused (0) */
UCHAR Feature4; /* Unused (0) */
UCHAR Feature5; /* Unused (0) */
} MP_FLOATING_POINTER, *PMP_FLOATING_POINTER;
#define FEATURE2_IMCRP 0x80
/* MP Configuration Table Header */
#define MPC_SIGNATURE (('P' << 24) | ('M' << 16) | ('C' << 8) | 'P')
typedef struct _MP_CONFIGURATION_TABLE
{
ULONG Signature; /* PCMP */
USHORT Length; /* Size of configuration table */
CHAR Specification; /* Specification Revision */
CHAR Checksum; /* Checksum */
CHAR Oem[8]; /* OEM ID */
CHAR ProductId[12]; /* Product ID */
ULONG OemTable; /* 0 if not present */
USHORT OemTableSize; /* 0 if not present */
USHORT EntryCount; /* Number of entries */
ULONG LocalAPICAddress; /* Local APIC address */
USHORT ExtTableLength; /* Extended Table Length */
UCHAR ExtTableChecksum; /* Extended Table Checksum */
UCHAR Reserved; /* Reserved */
} MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
/* MP Configuration Table Entries */
#define MPCTE_PROCESSOR 0 /* One entry per processor */
#define MPCTE_BUS 1 /* One entry per bus */
#define MPCTE_IOAPIC 2 /* One entry per I/O APIC */
#define MPCTE_INTSRC 3 /* One entry per bus interrupt source */
#define MPCTE_LINTSRC 4 /* One entry per system interrupt source */
typedef struct _MP_CONFIGURATION_PROCESSOR
{
UCHAR Type; /* 0 */
UCHAR ApicId; /* Local APIC ID for the processor */
UCHAR ApicVersion; /* Local APIC version */
UCHAR CpuFlags; /* CPU flags */
ULONG CpuSignature; /* CPU signature */
ULONG FeatureFlags; /* CPUID feature value */
ULONG Reserved[2]; /* Reserved (0) */
} MP_CONFIGURATION_PROCESSOR, *PMP_CONFIGURATION_PROCESSOR;
typedef struct _MP_CONFIGURATION_BUS
{
UCHAR Type; /* 1 */
UCHAR BusId; /* Bus ID */
CHAR BusType[6]; /* Bus type */
} MP_CONFIGURATION_BUS, *PMP_CONFIGURATION_BUS;
#define MAX_BUS 32
#define MP_BUS_ISA 1
#define MP_BUS_EISA 2
#define MP_BUS_PCI 3
#define MP_BUS_MCA 4
#define BUSTYPE_EISA "EISA"
#define BUSTYPE_ISA "ISA"
#define BUSTYPE_INTERN "INTERN" /* Internal BUS */
#define BUSTYPE_MCA "MCA"
#define BUSTYPE_VL "VL" /* Local bus */
#define BUSTYPE_PCI "PCI"
#define BUSTYPE_PCMCIA "PCMCIA"
#define BUSTYPE_CBUS "CBUS"
#define BUSTYPE_CBUSII "CBUSII"
#define BUSTYPE_FUTURE "FUTURE"
#define BUSTYPE_MBI "MBI"
#define BUSTYPE_MBII "MBII"
#define BUSTYPE_MPI "MPI"
#define BUSTYPE_MPSA "MPSA"
#define BUSTYPE_NUBUS "NUBUS"
#define BUSTYPE_TC "TC"
#define BUSTYPE_VME "VME"
#define BUSTYPE_XPRESS "XPRESS"
typedef struct _MP_CONFIGURATION_IOAPIC
{
UCHAR Type; /* 2 */
UCHAR ApicId; /* I/O APIC ID */
UCHAR ApicVersion; /* I/O APIC version */
UCHAR ApicFlags; /* I/O APIC flags */
ULONG ApicAddress; /* I/O APIC base address */
} MP_CONFIGURATION_IOAPIC, *PMP_CONFIGURATION_IOAPIC;
#define MAX_IOAPIC 2
#define MP_IOAPIC_USABLE 0x01
typedef struct _MP_CONFIGURATION_INTSRC
{
UCHAR Type; /* 3 */
UCHAR IrqType; /* Interrupt type */
USHORT IrqFlag; /* Interrupt flags */
UCHAR SrcBusId; /* Source bus ID */
UCHAR SrcBusIrq; /* Source bus interrupt */
UCHAR DstApicId; /* Destination APIC ID */
UCHAR DstApicInt; /* Destination interrupt */
} MP_CONFIGURATION_INTSRC, *PMP_CONFIGURATION_INTSRC;
#define MAX_IRQ_SOURCE 128
#define INT_VECTORED 0
#define INT_NMI 1
#define INT_SMI 2
#define INT_EXTINT 3
#define IRQDIR_DEFAULT 0
#define IRQDIR_HIGH 1
#define IRQDIR_LOW 3
typedef struct _MP_CONFIGURATION_INTLOCAL
{
UCHAR Type; /* 4 */
UCHAR IrqType; /* Interrupt type */
USHORT IrqFlag; /* Interrupt flags */
UCHAR SrcBusId; /* Source bus ID */
UCHAR SrcBusIrq; /* Source bus interrupt */
UCHAR DstApicId; /* Destination local APIC ID */
UCHAR DstApicLInt; /* Destination local APIC interrupt */
} MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL;
#include <poppack.h>
#define MP_APIC_ALL 0xFF
#define CPU_FLAG_ENABLED 1 /* Processor is available */
#define CPU_FLAG_BSP 2 /* Processor is the bootstrap processor */
#define CPU_STEPPING_MASK 0x0F
#define CPU_MODEL_MASK 0xF0
#define CPU_FAMILY_MASK 0xF00
#define PIC_IRQS 16
/* Prototypes */
VOID HalpInitMPS(VOID);
/* EOF */

View file

@ -1,31 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halppc/up/halinit_up.c
* PURPOSE: Initialize the x86 hal
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 11/06/98: Created
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
VOID
HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
}
VOID
HalpInitPhase1(VOID)
{
}
/* EOF */

View file

@ -1,5 +0,0 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer"
#define REACTOS_STR_INTERNAL_NAME "halup"
#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll"
#include <reactos/version.rc>

View file

@ -1,851 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/powerpc/cmhardwr.c
* PURPOSE: Configuration Manager - Hardware-Specific Code
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
PCHAR CmpID1 = "PowerPC %u";
PCHAR CmpID2 = "No Data";
PCHAR CmpBiosStrings[] =
{
"Ver",
"Rev",
"Rel",
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
"v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9",
NULL
};
PCHAR CmpBiosBegin, CmpBiosSearchStart, CmpBiosSearchEnd;
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
CmpGetBiosDate(IN PCHAR BiosStart,
IN ULONG BiosLength,
IN PCHAR BiosDate,
IN BOOLEAN FromBios)
{
CHAR LastDate[11] = {0}, CurrentDate[11];
PCHAR p, pp;
/* Skip the signature and the magic, and loop the BIOS ROM */
p = BiosStart + 2;
pp = BiosStart + BiosLength - 5;
while (p < pp)
{
/* Check for xx/yy/zz which we assume to be a date */
if ((p[0] == '/') &&
(p[3] == '/') &&
(isdigit(p[-1])) &&
(isdigit(p[1])) &&
(isdigit(p[2])) &&
(isdigit(p[4])) &&
(isdigit(p[5])))
{
/* Copy the string proper */
RtlMoveMemory(&CurrentDate[5], p - 2, 5);
/* Add a 0 if the month only has one digit */
if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0';
/* Now copy the year */
CurrentDate[2] = p[4];
CurrentDate[3] = p[5];
CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL;
/* If the date comes from the BIOS, check if it's a 4-digit year */
if ((FromBios) &&
(isdigit(p[6])) &&
(isdigit(p[7])) &&
((RtlEqualMemory(&p[4], "19", 2)) ||
(RtlEqualMemory(&p[4], "20", 2))))
{
/* Copy the year proper */
CurrentDate[0] = p[4];
CurrentDate[1] = p[5];
CurrentDate[2] = p[6];
CurrentDate[3] = p[7];
}
else
{
/* Otherwise, we'll just assume anything under 80 is 2000 */
if (strtoul(&CurrentDate[2], NULL, 10) < 80)
{
/* Hopefully your BIOS wasn't made in 1979 */
CurrentDate[0] = '2';
CurrentDate[1] = '0';
}
else
{
/* Anything over 80, was probably made in the 1900s... */
CurrentDate[0] = '1';
CurrentDate[1] = '9';
}
}
/* Add slashes where we previously had NULLs */
CurrentDate[4] = CurrentDate[7] = '/';
/* Check which date is newer */
if (memcmp(LastDate, CurrentDate, 10) < 0)
{
/* Found a newer date, select it */
RtlMoveMemory(LastDate, CurrentDate, 10);
}
p += 2;
}
p++;
}
/* Make sure we found a date */
if (LastDate[0])
{
/* Copy the year at the pp, and keep only the last two digits */
RtlMoveMemory(BiosDate, &LastDate[5], 5);
BiosDate[5] = '/';
BiosDate[6] = LastDate[2];
BiosDate[7] = LastDate[3];
BiosDate[8] = ANSI_NULL;
return TRUE;
}
/* No date found, return empty string */
BiosDate[0] = ANSI_NULL;
return FALSE;
}
BOOLEAN
NTAPI
CmpGetBiosVersion(IN PCHAR BiosStart,
IN ULONG BiosLength,
IN PCHAR BiosVersion)
{
CHAR Buffer[128];
PCHAR p, pp;
USHORT i;
/* Check if we were given intitial data for the search */
if (BiosStart)
{
/* Save it for later use */
CmpBiosBegin = BiosStart;
CmpBiosSearchStart = BiosStart + 1;
CmpBiosSearchEnd = BiosStart + BiosLength - 2;
}
/* Now loop the BIOS area */
for (;;)
{
/* Start an initial search looking for numbers and periods */
pp = NULL;
while (CmpBiosSearchStart <= CmpBiosSearchEnd)
{
/* Check if we have an "x.y" version string */
if ((*CmpBiosSearchStart == '.') &&
(*(CmpBiosSearchStart + 1) >= '0') &&
(*(CmpBiosSearchStart + 1) <= '9') &&
(*(CmpBiosSearchStart - 1) >= '0') &&
(*(CmpBiosSearchStart - 1) <= '9'))
{
/* Start looking in this area for the actual BIOS Version */
pp = CmpBiosSearchStart;
break;
}
else
{
/* Keep searching */
CmpBiosSearchStart++;
}
}
/* Break out if we're went past the BIOS area */
if (CmpBiosSearchStart > CmpBiosSearchEnd) return FALSE;
/* Move to the next 2 bytes */
CmpBiosSearchStart += 2;
/* Null-terminate our scratch buffer and start the string here */
Buffer[127] = ANSI_NULL;
p = &Buffer[127];
/* Go back one character since we're doing this backwards */
pp--;
/* Loop the identifier we found as long as it's valid */
i = 0;
while ((i++ < 127) &&
(pp >= CmpBiosBegin) &&
(*pp >= ' ') &&
(*pp != '$'))
{
/* Copy the character */
*--p = *pp--;
}
/* Go past the last character since we went backwards */
pp++;
/* Loop the strings we recognize */
for (i = 0; CmpBiosStrings[i]; i++)
{
/* Check if a match was found */
if (strstr(p, CmpBiosStrings[i])) goto Match;
}
}
Match:
/* Skip until we find a space */
for (; *pp == ' '; pp++);
/* Loop the final string */
i = 0;
do
{
/* Copy the character into the final string */
BiosVersion[i] = *pp++;
} while ((++i < 127) &&
(pp <= (CmpBiosSearchEnd + 1)) &&
(*pp >= ' ') &&
(*pp != '$'));
/* Null-terminate the version string */
BiosVersion[i] = ANSI_NULL;
return TRUE;
}
NTSTATUS
NTAPI
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
UNICODE_STRING KeyName, ValueName, Data, SectionName;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG HavePae, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition;
NTSTATUS Status;
HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
CONFIGURATION_COMPONENT_DATA ConfigData;
CHAR Buffer[128];
ULONG ExtendedId = 0; //, Dummy;
PKPRCB Prcb;
USHORT IndexTable[MaximumType + 1] = {0};
ANSI_STRING TempString;
PCHAR PartialString = NULL, BiosVersion;
CHAR CpuString[48];
PVOID BaseAddress = NULL;
LARGE_INTEGER ViewBase = {{0, 0}};
ULONG_PTR VideoRomBase;
PCHAR CurrentVersion;
extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion;
/* Open the SMSS Memory Management key */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
L"Control\\Session Manager\\Memory Management");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Detect if PAE is enabled */
HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];
/* Set the value */
RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_DWORD,
&HavePae,
sizeof(HavePae));
/* Close the key */
NtClose(KeyHandle);
}
/* Open the hardware description key */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\Description\\System");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
if (!NT_SUCCESS(Status))
return Status;
/* Create the BIOS Information key */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
L"Control\\BIOSINFO");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateKey(&BiosHandle,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
&Disposition);
if (!NT_SUCCESS(Status))
{
NtClose(SystemHandle);
return Status;
}
/* Create the CPU Key, and check if it already existed */
RtlInitUnicodeString(&KeyName, L"CentralProcessor");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
SystemHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
NtClose(KeyHandle);
/* The key shouldn't already exist */
if (Disposition == REG_CREATED_NEW_KEY)
{
/* Allocate the configuration data for cmconfig.c */
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
CmpConfigurationAreaSize,
TAG_CM);
if (!CmpConfigurationData)
{
// FIXME: Cleanup stuff!!
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Loop all CPUs */
for (i = 0; i < KeNumberProcessors; i++)
{
/* Get the PRCB */
Prcb = KiProcessorBlock[i];
/* Setup the Configuration Entry for the Processor */
RtlZeroMemory(&ConfigData, sizeof(ConfigData));
ConfigData.ComponentEntry.Class = ProcessorClass;
ConfigData.ComponentEntry.Type = CentralProcessor;
ConfigData.ComponentEntry.Key = i;
ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
ConfigData.ComponentEntry.Identifier = Buffer;
/* Check if the CPU doesn't support CPUID */
if (!Prcb->CpuID)
{
/* Build ID1-style string for older CPUs */
sprintf(Buffer,
CmpID1,
Prcb->CpuType,
(Prcb->CpuStep >> 8) + 'A',
Prcb->CpuStep & 0xff);
}
else
{
/* Build ID2-style string for newer CPUs */
sprintf(Buffer,
CmpID2,
Prcb->CpuType,
(Prcb->CpuStep >> 8),
Prcb->CpuStep & 0xff);
}
/* Save the ID string length now that we've created it */
ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1;
/* Initialize the registry configuration node for it */
Status = CmpInitializeRegistryNode(&ConfigData,
SystemHandle,
&KeyHandle,
InterfaceTypeUndefined,
0xFFFFFFFF,
IndexTable);
if (!NT_SUCCESS(Status))
{
NtClose(BiosHandle);
NtClose(SystemHandle);
return Status;
}
{
/* Setup the Configuration Entry for the FPU */
RtlZeroMemory(&ConfigData, sizeof(ConfigData));
ConfigData.ComponentEntry.Class = ProcessorClass;
ConfigData.ComponentEntry.Type = FloatingPointProcessor;
ConfigData.ComponentEntry.Key = i;
ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
ConfigData.ComponentEntry.Identifier = Buffer;
/* For 386 cpus, the CPU pp is the identifier */
if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
/* Save the ID string length now that we've created it */
ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1;
/* Initialize the registry configuration node for it */
Status = CmpInitializeRegistryNode(&ConfigData,
SystemHandle,
&FpuHandle,
InterfaceTypeUndefined,
0xFFFFFFFF,
IndexTable);
if (!NT_SUCCESS(Status))
{
/* We failed, close all the opened handles and return */
NtClose(KeyHandle);
NtClose(BiosHandle);
NtClose(SystemHandle);
return Status;
}
/* Close this new handle */
NtClose(FpuHandle);
/* Stay on this CPU only */
KeSetSystemAffinityThread(Prcb->SetMember);
if (!Prcb->CpuID)
{
/* Uh oh, no CPUID! */
}
else
{
/* Check if we have extended CPUID that supports name ID */
//Ki386Cpuid(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy);
if (ExtendedId >= 0x80000004)
{
/* Do all the CPUIDs required to get the full name */
PartialString = CpuString;
for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
{
#if 0
/* Do the CPUID and save the name string */
Ki386Cpuid(0x80000000 | ExtendedId,
(PULONG)PartialString,
(PULONG)PartialString + 1,
(PULONG)PartialString + 2,
(PULONG)PartialString + 3);
#endif
/* Go to the next name string */
PartialString += 16;
}
/* Null-terminate it */
CpuString[47] = ANSI_NULL;
}
}
/* Get the cache size while we're still localized */
CacheSize = 0; //((PKIPCR)KeGetPcr())->SecondLevelCacheSize;
/* Go back to user affinity */
KeRevertToUserAffinityThread();
/* Check if we have a CPU Name */
if (PartialString)
{
/* Convert it to Unicode */
RtlInitAnsiString(&TempString, CpuString);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Add it to the registry */
RtlInitUnicodeString(&ValueName, L"ProcessorNameString");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
Data.Buffer,
Data.Length + sizeof(UNICODE_NULL));
/* ROS: Save a copy for bugzilla reporting */
RtlCreateUnicodeString(&KeRosProcessorName, Data.Buffer);
/* Free the temporary buffer */
RtlFreeUnicodeString(&Data);
}
/* Check if we had a Vendor ID */
if (Prcb->VendorString)
{
/* Convert it to Unicode */
RtlInitAnsiString(&TempString, Prcb->VendorString);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Add it to the registry */
RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
Data.Buffer,
Data.Length + sizeof(UNICODE_NULL));
/* Free the temporary buffer */
RtlFreeUnicodeString(&Data);
}
/* Check if we have features bits */
if (Prcb->FeatureBits)
{
/* Add them to the registry */
RtlInitUnicodeString(&ValueName, L"FeatureSet");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_DWORD,
&Prcb->FeatureBits,
sizeof(Prcb->FeatureBits));
}
/* Check if we detected the CPU Speed */
if (Prcb->MHz)
{
/* Add it to the registry */
RtlInitUnicodeString(&ValueName, L"~MHz");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_DWORD,
&Prcb->MHz,
sizeof(Prcb->MHz));
}
/* Check if we have an update signature */
if (Prcb->UpdateSignature.QuadPart)
{
/* Add it to the registry */
RtlInitUnicodeString(&ValueName, L"Update Signature");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_BINARY,
&Prcb->UpdateSignature,
sizeof(Prcb->UpdateSignature));
}
/* Close the processor handle */
NtClose(KeyHandle);
/* FIXME: Detect CPU mismatches */
}
}
/* Free the configuration data */
ExFreePoolWithTag(CmpConfigurationData, TAG_CM);
}
/* Open physical memory */
RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&ObjectAttributes,
&SectionName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenSection(&SectionHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
/* We failed, close all the opened handles and return */
// NtClose(KeyHandle);
NtClose(BiosHandle);
NtClose(SystemHandle);
/* 'Quickie' closes KeyHandle */
goto Quickie;
}
/* Map the first 1KB of memory to get the IVT */
ViewSize = PAGE_SIZE;
Status = ZwMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&ViewBase,
&ViewSize,
ViewUnmap,
MEM_DOS_LIM,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* Assume default */
VideoRomBase = 0xC0000;
}
else
{
/* Calculate the base address from the vector */
VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0;
VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0;
/* Now get to the actual ROM Start and make sure it's not invalid*/
VideoRomBase &= 0xFFFF8000;
if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000;
/* And unmap the section */
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
/* Allocate BIOS Version pp Buffer */
BiosVersion = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
/* Setup settings to map the 64K BIOS ROM */
BaseAddress = 0;
ViewSize = 16 * PAGE_SIZE;
ViewBase.LowPart = 0xF0000;
ViewBase.HighPart = 0;
/* Map it */
Status = ZwMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&ViewBase,
&ViewSize,
ViewUnmap,
MEM_DOS_LIM,
PAGE_READWRITE);
if (NT_SUCCESS(Status))
{
/* Scan the ROM to get the BIOS Date */
if (CmpGetBiosDate(BaseAddress, 16 * PAGE_SIZE, Buffer, TRUE))
{
/* Convert it to Unicode */
RtlInitAnsiString(&TempString, Buffer);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Write the date into the registry */
RtlInitUnicodeString(&ValueName, L"SystemBiosDate");
Status = NtSetValueKey(SystemHandle,
&ValueName,
0,
REG_SZ,
Data.Buffer,
Data.Length + sizeof(UNICODE_NULL));
/* Free the string */
RtlFreeUnicodeString(&Data);
if (BiosHandle)
{
/* Get the BIOS Date Identifier */
RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16*PAGE_SIZE - 11), 8);
Buffer[8] = ANSI_NULL;
/* Convert it to unicode */
RtlInitAnsiString(&TempString, Buffer);
Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
if (NT_SUCCESS(Status))
{
/* Save it to the registry */
Status = NtSetValueKey(BiosHandle,
&ValueName,
0,
REG_SZ,
Data.Buffer,
Data.Length + sizeof(UNICODE_NULL));
/* ROS: Save a copy for bugzilla reporting */
RtlCreateUnicodeString(&KeRosBiosDate, Data.Buffer);
/* Free the string */
RtlFreeUnicodeString(&Data);
}
/* Close the bios information handle */
NtClose(BiosHandle);
}
}
/* Get the BIOS Version */
if (CmpGetBiosVersion(BaseAddress, 16* PAGE_SIZE, Buffer))
{
/* Start at the beginning of our buffer */
CurrentVersion = BiosVersion;
do
{
/* Convert to Unicode */
RtlInitAnsiString(&TempString, Buffer);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Calculate the length of this string and copy it in */
Length = Data.Length + sizeof(UNICODE_NULL);
RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
/* Free the unicode string */
RtlFreeUnicodeString(&Data);
/* Update the total length and see if we're out of space */
TotalLength += Length;
if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
{
/* One more string would push us out, so stop here */
break;
}
/* Go to the next string inside the multi-string buffer */
CurrentVersion += Length;
/* Query the next BIOS Version */
} while (CmpGetBiosVersion(NULL, 0, Buffer));
/* Check if we found any strings at all */
if (TotalLength)
{
/* Add the final null-terminator */
*(PWSTR)CurrentVersion = UNICODE_NULL;
TotalLength += sizeof(UNICODE_NULL);
/* Write the BIOS Version to the registry */
RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
Status = NtSetValueKey(SystemHandle,
&ValueName,
0,
REG_MULTI_SZ,
BiosVersion,
TotalLength);
/* ROS: Save a copy for bugzilla reporting */
RtlCreateUnicodeString(&KeRosBiosVersion, (PWCH)BiosVersion);
}
}
/* Unmap the section */
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
/* Now prepare for Video BIOS Mapping of 32KB */
BaseAddress = 0;
ViewSize = 8 * PAGE_SIZE;
ViewBase.LowPart = VideoRomBase;
ViewBase.HighPart = 0;
/* Map it */
Status = ZwMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&ViewBase,
&ViewSize,
ViewUnmap,
MEM_DOS_LIM,
PAGE_READWRITE);
if (NT_SUCCESS(Status))
{
/* Scan the ROM to get the BIOS Date */
if (CmpGetBiosDate(BaseAddress, 8 * PAGE_SIZE, Buffer, FALSE))
{
/* Convert it to Unicode */
RtlInitAnsiString(&TempString, Buffer);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Write the date into the registry */
RtlInitUnicodeString(&ValueName, L"VideoBiosDate");
Status = NtSetValueKey(SystemHandle,
&ValueName,
0,
REG_SZ,
Data.Buffer,
Data.Length + sizeof(UNICODE_NULL));
/* ROS: Save a copy for bugzilla reporting */
RtlCreateUnicodeString(&KeRosVideoBiosDate, Data.Buffer);
/* Free the string */
RtlFreeUnicodeString(&Data);
}
/* Get the Video BIOS Version */
if (CmpGetBiosVersion(BaseAddress, 8* PAGE_SIZE, Buffer))
{
/* Start at the beginning of our buffer */
CurrentVersion = BiosVersion;
do
{
/* Convert to Unicode */
RtlInitAnsiString(&TempString, Buffer);
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
/* Calculate the length of this string and copy it in */
Length = Data.Length + sizeof(UNICODE_NULL);
RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
/* Free the unicode string */
RtlFreeUnicodeString(&Data);
/* Update the total length and see if we're out of space */
TotalLength += Length;
if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
{
/* One more string would push us out, so stop here */
break;
}
/* Go to the next string inside the multi-string buffer */
CurrentVersion += Length;
/* Query the next BIOS Version */
} while (CmpGetBiosVersion(NULL, 0, Buffer));
/* Check if we found any strings at all */
if (TotalLength)
{
/* Add the final null-terminator */
*(PWSTR)CurrentVersion = UNICODE_NULL;
TotalLength += sizeof(UNICODE_NULL);
/* Write the BIOS Version to the registry */
RtlInitUnicodeString(&ValueName, L"VideoBiosVersion");
Status = NtSetValueKey(SystemHandle,
&ValueName,
0,
REG_MULTI_SZ,
BiosVersion,
TotalLength);
/* ROS: Save a copy for bugzilla reporting */
RtlCreateUnicodeString(&KeRosVideoBiosVersion, (PWCH)BiosVersion);
}
}
/* Unmap the section */
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
/* Close the section */
ZwClose(SectionHandle);
/* Free the BIOS version string buffer */
if (BiosVersion) ExFreePoolWithTag(BiosVersion, TAG_CM);
Quickie:
/* Close the processor handle */
NtClose(KeyHandle);
return STATUS_SUCCESS;
}

View file

@ -1,171 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/powerpc/ioport.s
* PURPOSE: FASTCALL Interlocked Functions
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
/* GLOBALS *******************************************************************/
.globl READ_REGISTER_UCHAR
.globl READ_REGISTER_USHORT
.globl READ_REGISTER_ULONG
.globl READ_REGISTER_BUFFER_UCHAR
.globl READ_REGISTER_BUFFER_USHORT
.globl READ_REGISTER_BUFFER_ULONG
.globl WRITE_REGISTER_UCHAR
.globl WRITE_REGISTER_USHORT
.globl WRITE_REGISTER_ULONG
.globl WRITE_REGISTER_BUFFER_UCHAR
.globl WRITE_REGISTER_BUFFER_USHORT
.globl WRITE_REGISTER_BUFFER_ULONG
/* FUNCTIONS *****************************************************************/
READ_REGISTER_UCHAR:
/* Return the requested memory location */
sync
eieio
lbz 3,0(3)
blr
READ_REGISTER_USHORT:
/* Return the requested memory location */
sync
eieio
lhz 3,0(3)
blr
READ_REGISTER_ULONG:
/* Return the requested memory location */
sync
eieio
lwz 3,0(3)
blr
READ_REGISTER_BUFFER_UCHAR:
1:
cmpwi 0,5,0
beq 2f
lbz 0,0(4)
stb 0,0(3)
addi 3,3,1
addi 4,4,1
subi 5,5,1
b 1b
2:
eieio
sync
blr
READ_REGISTER_BUFFER_USHORT:
1:
cmpwi 0,5,0
beq 2f
lhz 0,0(4)
sth 0,0(3)
addi 3,3,2
addi 4,4,2
subi 5,5,2
b 1b
2:
eieio
sync
blr
READ_REGISTER_BUFFER_ULONG:
1:
cmpwi 0,5,0
beq 2f
lwz 0,0(4)
stw 0,0(3)
addi 3,3,4
addi 4,4,4
subi 5,5,4
b 1b
2:
eieio
sync
blr
WRITE_REGISTER_UCHAR:
stb 4,0(3)
eieio
sync
blr
WRITE_REGISTER_USHORT:
sth 4,0(3)
eieio
sync
blr
WRITE_REGISTER_ULONG:
stw 4,0(3)
eieio
sync
blr
WRITE_REGISTER_BUFFER_UCHAR:
sync
eieio
1:
cmpwi 0,5,0
beq 2f
lbz 0,0(4)
stb 0,0(3)
addi 3,3,1
addi 4,4,1
subi 5,5,1
b 1b
2:
blr
WRITE_REGISTER_BUFFER_USHORT:
sync
eieio
1:
cmpwi 0,5,0
beq 2f
lhz 0,0(4)
sth 0,0(3)
addi 3,3,2
addi 4,4,2
subi 5,5,2
b 1b
2:
blr
WRITE_REGISTER_BUFFER_ULONG:
sync
eieio
1:
cmpwi 0,5,0
beq 2f
lwz 0,0(4)
stw 0,0(3)
addi 3,3,4
addi 4,4,4
subi 5,5,4
b 1b
2:
blr
/* EOF */

View file

@ -1,5 +0,0 @@
#pragma once
#define Ke386SaveFlags(x) __asm__ __volatile__("mfmsr %0" : "=r" (x) :)
/* EOF */

View file

@ -1,132 +0,0 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* 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
#include <ndk/powerpc/ketypes.h>
/* Possible values for KTHREAD's NpxState */
#define KPCR_BASE 0xff000000
#define NPX_STATE_INVALID 0x01
#define NPX_STATE_VALID 0x02
#define NPX_STATE_DIRTY 0x04
#ifndef __ASM__
typedef struct _KIRQ_TRAPFRAME
{
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
extern ULONG KePPCCacheAlignment;
//#define KD_BREAKPOINT_TYPE
//#define KD_BREAKPOINT_SIZE
//#define KD_BREAKPOINT_VALUE
//
// Macro to get the second level cache size field name which differs between
// CISC and RISC architectures, as the former has unified I/D cache
//
#define KiGetSecondLevelDCacheSize() ((PKIPCR)KeGetPcr())->SecondLevelDcacheSize
//
// Macros for getting and setting special purpose registers in portable code
//
#define KeGetContextPc(Context) \
((Context)->Dr0)
#define KeSetContextPc(Context, ProgramCounter) \
((Context)->Dr0 = (ProgramCounter))
#define KeGetTrapFramePc(TrapFrame) \
((TrapFrame)->Dr0)
#define KeGetContextReturnRegister(Context) \
((Context)->Gpr3)
#define KeSetContextReturnRegister(Context, ReturnValue) \
((Context)->Gpr3 = (ReturnValue))
//
// Returns the Interrupt State from a Trap Frame.
// ON = TRUE, OFF = FALSE
//
//#define KeGetTrapFrameInterruptState(TrapFrame) \
#define KePPCRdmsr(msr,val1,val2) __asm__ __volatile__("mfmsr 3")
#define KePPCWrmsr(msr,val1,val2) __asm__ __volatile__("mtmsr 3")
#define PPC_MIN_CACHE_LINE_SIZE 32
FORCEINLINE struct _KPCR * NTHALAPI KeGetCurrentKPCR(
VOID)
{
return (struct _KPCR *)__readfsdword(0x1c);
}
FORCEINLINE
VOID
KeFlushProcessTb(VOID)
{
/* Flush the TLB */
__asm__("sync\n\tisync\n\t");
}
FORCEINLINE
VOID
KeSweepICache(IN PVOID BaseAddress,
IN SIZE_T FlushSize)
{
//
// Always sweep the whole cache
//
UNREFERENCED_PARAMETER(BaseAddress);
UNREFERENCED_PARAMETER(FlushSize);
__asm__ __volatile__("tlbsync");
}
FORCEINLINE
PRKTHREAD
KeGetCurrentThread(VOID)
{
/* Return the current thread */
return KeGetCurrentPrcb()->CurrentThread;
}
FORCEINLINE
VOID
KiRundownThread(IN PKTHREAD Thread)
{
/* FIXME */
}
#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
VOID
NTAPI
KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
BOOLEAN UserThread,
KTRAP_FRAME TrapFrame);
#endif
#endif /* __ASM__ */
/* EOF */

View file

@ -1,271 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/powerpc/cpu.c
* PURPOSE: Routines for CPU-level support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
/* CPU Features and Flags */
ULONG KeLargestCacheLine = 0x40;
ULONG KeDcacheFlushCount = 0;
ULONG KeIcacheFlushCount = 0;
ULONG KiDmaIoCoherency = 0;
BOOLEAN KiSMTProcessorsPresent;
/* CPU Signatures */
#if 0
CHAR CmpIntelID[] = "GenuineIntel";
CHAR CmpAmdID[] = "AuthenticAMD";
CHAR CmpCyrixID[] = "CyrixInstead";
CHAR CmpTransmetaID[] = "GenuineTMx86";
CHAR CmpCentaurID[] = "CentaurHauls";
CHAR CmpRiseID[] = "RiseRiseRise";
#endif
/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
VOID
NTAPI
CPUID(IN ULONG CpuInfo[4],
IN ULONG InfoType)
{
RtlZeroMemory(CpuInfo, 4 * sizeof(ULONG));
}
VOID
WRMSR(IN ULONG Register,
IN LONGLONG Value)
{
}
LONGLONG
RDMSR(IN ULONG Register)
{
LARGE_INTEGER LargeVal;
LargeVal.QuadPart = 0;
return LargeVal.QuadPart;
}
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
KiSetProcessorType(VOID)
{
}
ULONG
NTAPI
KiGetCpuVendor(VOID)
{
return 0;
}
ULONG
NTAPI
KiGetFeatureBits(VOID)
{
ULONG FeatureBits = 0;
/* Return the Feature Bits */
return FeatureBits;
}
VOID
NTAPI
KiGetCacheInformation(VOID)
{
}
VOID
NTAPI
KiSetCR0Bits(VOID)
{
}
VOID
NTAPI
KiInitializeTSS2(IN PKTSS Tss,
IN PKGDTENTRY TssEntry OPTIONAL)
{
}
VOID
NTAPI
KiInitializeTSS(IN PKTSS Tss)
{
}
VOID
FASTCALL
Ki386InitializeTss(IN PKTSS Tss,
IN PKIDTENTRY Idt,
IN PKGDTENTRY Gdt)
{
}
VOID
NTAPI
KeFlushCurrentTb(VOID)
{
}
VOID
NTAPI
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
{
}
VOID
NTAPI
KiInitializeMachineType(VOID)
{
}
ULONG_PTR
NTAPI
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
return 0;
}
VOID
NTAPI
KiRestoreFastSyscallReturnState(VOID)
{
}
ULONG_PTR
NTAPI
Ki386EnableDE(IN ULONG_PTR Context)
{
return 0;
}
ULONG_PTR
NTAPI
Ki386EnableFxsr(IN ULONG_PTR Context)
{
return 0;
}
ULONG_PTR
NTAPI
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
{
/* FIXME: Support this */
DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n");
return 0;
}
VOID
NTAPI
KiI386PentiumLockErrataFixup(VOID)
{
/* FIXME: Support this */
DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
{
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
{
return STATUS_SUCCESS;
}
/*
* @implemented
*/
ULONG
NTAPI
KeGetRecommendedSharedDataAlignment(VOID)
{
/* Return the global variable */
return KeLargestCacheLine;
}
/*
* @implemented
*/
VOID
NTAPI
KeFlushEntireTb(IN BOOLEAN Invalid,
IN BOOLEAN AllProcessors)
{
KIRQL OldIrql;
/* Raise the IRQL for the TB Flush */
OldIrql = KeRaiseIrqlToSynchLevel();
#ifdef CONFIG_SMP
/* FIXME: Support IPI Flush */
#error Not yet implemented!
#endif
/* Flush the TB for the Current CPU */
//KeFlushCurrentTb();
/* Return to Original IRQL */
KeLowerIrql(OldIrql);
}
/*
* @implemented
*/
VOID
NTAPI
KeSetDmaIoCoherency(IN ULONG Coherency)
{
/* Save the coherency globally */
KiDmaIoCoherency = Coherency;
}
/*
* @implemented
*/
KAFFINITY
NTAPI
KeQueryActiveProcessors(VOID)
{
PAGED_CODE();
/* Simply return the number of active processors */
return KeActiveProcessors;
}
/*
* @implemented
*/
VOID
__cdecl
KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
{
/* Capture the context */
RtlCaptureContext(&State->ContextFrame);
/* Capture the control state */
KiSaveProcessorControlState(State);
}

View file

@ -1,252 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/powerpc/ctxhelp.S
* PURPOSE: Thread Context Switching
*
* PROGRAMMERS: arty
(i386 implementation by Alex Ionescu)
*/
/* INCLUDES ******************************************************************/
.text
.globl syscall_start
.globl syscall_end
.globl KiSystemService
syscall_start:
mtsprg0 0
mtsprg1 1
/* Save and modify srr0 */
/* Make a place to store the old srr0 and srr1 ... we may fault
* getting KiSystemService1 which will clobber them. */
lis 1,1
mfsrr0 0
stw 0,-16(1)
mfsrr1 0
stw 0,-12(1)
/* Load the target address */
lis 1,KiSystemService1@ha
addi 1,1,KiSystemService1@l
mtsrr0 1
mfsprg0 0
mfsprg1 1
rfi
syscall_end:
.space 4
.globl KiSystemService
.globl KiSystemService1
.globl kiss_proceed
.globl kiss_end
.align 8
KiSystemService1:
stwu 1,-256(1)
stw 0,16(1)
mflr 0
stw 0,264(1)
addi 1,1,16
stw 2,8(1)
stw 3,12(1)
stw 4,16(1)
stw 5,20(1)
stw 6,24(1)
stw 7,28(1)
stw 8,32(1)
stw 9,36(1)
stw 10,40(1)
stw 11,44(1)
stw 12,48(1)
stw 13,52(1)
stw 14,56(1)
stw 15,60(1)
stw 16,64(1)
stw 17,68(1)
stw 18,72(1)
stw 19,76(1)
stw 20,80(1)
stw 21,84(1)
stw 22,88(1)
stw 23,92(1)
stw 24,96(1)
stw 25,100(1)
stw 26,104(1)
stw 27,108(1)
stw 28,112(1)
stw 29,116(1)
stw 30,120(1)
stw 31,124(1)
mflr 0
stw 0,128(1)
mfctr 0
stw 0,136(1)
mfmsr 0
andi. 0,0,0xffef
mtmsr 0
lis 2,1
lwz 30,-12(2)
lwz 31,-16(2)
mfmsr 0
ori 0,0,0x10
mtmsr 0
stw 31,140(1)
stw 30,144(1)
mfdsisr 0
stw 0,148(1)
mfdar 0
stw 0,152(1)
lis 3,KiSystemService@ha
addi 3,3,KiSystemService@l
mtctr 3
mr 3,1
subi 1,1,16
bctrl
addi 1,1,16
/* Return from kernel */
lwz 3,32(1) /* Result */
lwz 0,128(1)
mtlr 0
lwz 0,140(1)
mtsrr0 0
lwz 0,144(1)
mtsrr1 0
addi 1,1,0x100 - 16
rfi
.globl KiDecrementerTrapHandler
.globl KiDecrementerTrapHandlerEnd
.globl KiDecrementerTrap
KiDecrementerTrapHandler:
mtsprg0 0
mtsprg1 1
/* Save and modify srr0 */
/* Make a place to store the old srr0 and srr1 ... we may fault
* getting KiSystemService1 which will clobber them. */
lis 1,1
mfsprg1 0
stw 0,-24(1)
mfsrr1 0
stw 0,-28(1)
mfsrr0 0
stw 0,-32(1)
/* Load the target address */
lis 1,KiDecrementerTrapUpper@ha
addi 1,1,KiDecrementerTrapUpper@l
mtsrr0 1
mfsprg0 0
mfsprg1 1
rfi
KiDecrementerTrapHandlerEnd:
.long 0
/* Decrementer needs to restore the full CPU state */
.globl KiDecrementerTrapUpper
.align 8
KiDecrementerTrapUpper:
lis 1,_kernel_trap_stack@ha
addi 1,1,_kernel_trap_stack@l
subi 1,1,0x200
stw 0,0x5c(1)
/* Stack handled a bit later */
stw 2,0x64(1)
stw 3,0x68(1)
stw 4,0x6c(1)
stw 5,0x70(1)
stw 6,0x74(1)
stw 7,0x78(1)
stw 8,0x7c(1)
stw 9,0x80(1)
stw 10,0x84(1)
stw 11,0x88(1)
stw 12,0x8c(1)
stw 13,0x90(1)
stw 14,0x94(1)
stw 15,0x98(1)
stw 16,0x9c(1)
stw 17,0xa0(1)
stw 18,0xa4(1)
stw 19,0xa8(1)
stw 20,0xac(1)
stw 21,0xb0(1)
stw 22,0xb4(1)
stw 23,0xb8(1)
stw 24,0xbc(1)
stw 25,0xc0(1)
stw 26,0xc4(1)
stw 27,0xc8(1)
stw 28,0xcc(1)
stw 29,0xd0(1)
stw 30,0xd4(1)
stw 31,0xd8(1)
mfcr 0
stw 0,0x108(1)
mfxer 0
stw 0,0x10c(1)
mflr 0
stw 0,0x118(1)
mfctr 0
stw 0,0x11c(1)
mfmsr 0
andi. 0,0,0x7fef
mtmsr 0
lis 2,1
lwz 29,-24(2) // Stack
lwz 30,-28(2) // srr1
lwz 31,-32(2) // srr0
mfmsr 0
ori 0,0,0x30
mtmsr 0
stw 29,0x60(1) // Stack
stw 30,0x110(1) // srr1
stw 31,0x114(1) // srr0
mr 3,1
subi 1,1,16
bl KiDecrementerTrap
addi 1,1,16
lwz 2,0x64(1)
lwz 3,0x68(1)
lwz 4,0x6c(1)
lwz 5,0x70(1)
lwz 6,0x74(1)
lwz 7,0x78(1)
lwz 8,0x7c(1)
lwz 9,0x80(1)
lwz 10,0x84(1)
lwz 11,0x88(1)
lwz 12,0x8c(1)
lwz 13,0x90(1)
lwz 14,0x94(1)
lwz 15,0x98(1)
lwz 16,0x9c(1)
lwz 17,0xa0(1)
lwz 18,0xa4(1)
lwz 19,0xa8(1)
lwz 20,0xac(1)
lwz 21,0xb0(1)
lwz 22,0xb4(1)
lwz 23,0xb8(1)
lwz 24,0xbc(1)
lwz 25,0xc0(1)
lwz 26,0xc4(1)
lwz 27,0xc8(1)
lwz 28,0xcc(1)
lwz 29,0xd0(1)
lwz 30,0xd4(1)
lwz 31,0xd8(1)
lwz 0,0x108(1)
mtcr 0
lwz 0,0x10c(1)
mtxer 0
lwz 0,0x110(1)
mtsrr1 0
lwz 0,0x114(1)
mtsrr0 0
lwz 0,0x118(1)
mtlr 0
lwz 0,0x11c(1)
mtctr 0
// back out r0 and r1
lwz 0,0x5c(1)
lwz 1,0x60(1)
// Bye!!1
rfi

View file

@ -1,124 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/powerpc/ctxswitch.c
* PURPOSE: Thread Context Switching
*
* PROGRAMMERS: arty
(i386 implementation by Alex Ionescu)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
/*++
* KiThreadStartup
*
* The KiThreadStartup routine is the beginning of any thread.
*
* Params:
* SystemRoutine - Pointer to the System Startup Routine. Either
* PspUserThreadStartup or PspSystemThreadStartup
*
* StartRoutine - For Kernel Threads only, specifies the starting execution
* point of the new thread.
*
* StartContext - For Kernel Threads only, specifies a pointer to variable
* context data to be sent to the StartRoutine above.
*
* UserThread - Indicates whether or not this is a user thread. This tells
* us if the thread has a context or not.
*
* TrapFrame - Pointer to the KTHREAD to which the caller wishes to
* switch from.
*
* Returns:
* Should never return for a system thread. Returns through the System Call
* Exit Dispatcher for a user thread.
*
* Remarks:
* If a return from a system thread is detected, a bug check will occur.
*
*--*/
VOID
NTAPI
KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
BOOLEAN UserThread,
KTRAP_FRAME TrapFrame)
{
KeLowerIrql(APC_LEVEL);
__asm__("mr 0,%0\n\t"
"mr 3,%1\n\t"
"mr 4,%2\n\t"
"mr 5,%3\n\t"
"mr 6,%4\n\t"
"sc" : :
"r" (0xf0000), /* Thread start function */
"r" (SystemRoutine),
"r" (StartRoutine),
"r" (StartContext),
"r" (UserThread));
PspTerminateThreadByPointer(PsGetCurrentThread(), STATUS_THREAD_IS_TERMINATING, TRUE);
}
/* Take a decrementer trap, and prepare the given trap frame, swapping
* process and thread context as appropriate. */
VOID KiDecrementerTrapFinish(PKTRAP_FRAME TrapFrame);
VOID
FASTCALL
KiQueueReadyThread(IN PKTHREAD Thread,
IN PKPRCB Prcb);
PKTHREAD KiLastThread = NULL;
PKTRAP_FRAME KiLastThreadTrapFrame = NULL;
VOID
NTAPI
KiDecrementerTrap(PKTRAP_FRAME TrapFrame)
{
KIRQL Irql;
PKPRCB Prcb = KeGetPcr()->Prcb;
if (!KiLastThread)
KiLastThread = KeGetCurrentThread();
if (KiLastThread->State == Running)
KiQueueReadyThread(KiLastThread, Prcb);
if (!KiLastThreadTrapFrame)
KiLastThreadTrapFrame = Prcb->IdleThread->TrapFrame;
TrapFrame->OldIrql = KeGetCurrentIrql();
*KiLastThreadTrapFrame = *TrapFrame;
if (Prcb->NextThread)
{
Prcb->CurrentThread = Prcb->NextThread;
Prcb->NextThread = NULL;
}
else
Prcb->CurrentThread = Prcb->IdleThread;
Prcb->CurrentThread->State = Running;
KiLastThreadTrapFrame = Prcb->CurrentThread->TrapFrame;
KiLastThread = Prcb->CurrentThread;
*TrapFrame = *KiLastThreadTrapFrame;
Irql = KeGetCurrentIrql();
if (Irql > TrapFrame->OldIrql)
KfRaiseIrql(Irql);
else if (Irql < TrapFrame->OldIrql)
KfLowerIrql(Irql);
/* When we return, we'll go through rfi and be in new thread land */
__asm__("mtdec %0" : : "r" (0x1000000)); // Reset the trap
}

View file

@ -1,103 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/powerpc/exp.c
* PURPOSE: Exception Dispatching and Context<->Trap Frame Conversion
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Gregor Anich
* Skywing (skywing@valhallalegends.com)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
/* FUNCTIONS *****************************************************************/
CODE_SEG("INIT")
VOID
NTAPI
KeInitExceptions(VOID)
{
}
ULONG
NTAPI
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
{
return 0;
}
VOID
NTAPI
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
IN ULONG Esp)
{
}
ULONG
NTAPI
KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
{
return 0;
}
VOID
NTAPI
KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
IN ULONG Ss)
{
}
USHORT
NTAPI
KiTagWordFnsaveToFxsave(USHORT TagWord)
{
return 0;
}
VOID
NTAPI
KeContextToTrapFrame(IN PCONTEXT Context,
IN OUT PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PKTRAP_FRAME TrapFrame,
IN ULONG ContextFlags,
IN KPROCESSOR_MODE PreviousMode)
{
}
VOID
NTAPI
KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PCONTEXT Context)
{
}
VOID
NTAPI
KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN FirstChance)
{
DbgPrint("EXCEPTION! Record %08x Frame %08x\n",
ExceptionRecord, ExceptionFrame);
MmuDumpMap();
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
KeRaiseUserException(IN NTSTATUS ExceptionCode)
{
return STATUS_SUCCESS;
}

View file

@ -1,356 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/powerpc/kiinit.c
* PURPOSE: Kernel Initialization for x86 CPUs
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Art Yerkes (ayerkes@speakeasy.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
//#define NDEBUG
#include <debug.h>
#include "ppcmmu/mmu.h"
/* GLOBALS *******************************************************************/
/* Ku bit should be set, so that we get the best options for page protection */
#define PPC_SEG_Ku 0x40000000
#define PPC_SEG_Ks 0x20000000
extern LOADER_MODULE KeLoaderModules[64];
extern ULONG KeLoaderModuleCount;
extern ULONG_PTR MmFreeLdrLastKernelAddress;
KPRCB PrcbData[MAXIMUM_PROCESSORS];
/* BIOS Memory Map. Not NTLDR-compliant yet */
extern ULONG KeMemoryMapRangeCount;
extern ADDRESS_RANGE KeMemoryMap[64];
/* FUNCTIONS *****************************************************************/
/*
* Trap frame:
* r0 .. r32
* lr, ctr, srr0, srr1, dsisr
*/
extern int syscall_start[], syscall_end, KiDecrementerTrapHandler[],
KiDecrementerTrapHandlerEnd;
VOID
NTAPI
KiSetupSyscallHandler(VOID)
{
paddr_t handler_target;
int *source;
for(source = syscall_start, handler_target = 0xc00;
source < &syscall_end;
source++, handler_target += sizeof(int))
{
SetPhys(handler_target, *source);
}
}
VOID
NTAPI
KiSetupDecrementerTrap(VOID)
{
paddr_t handler_target;
int *source;
/* Turn off EE bit while redefining dec trap */
_disable();
for(source = KiDecrementerTrapHandler, handler_target = 0x900;
source != &KiDecrementerTrapHandlerEnd;
source++, handler_target += sizeof(int))
SetPhys(handler_target, *source);
DPRINT("CurrentThread %08x IdleThread %08x\n",
KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread);
/* Kick decmrenter! */
__asm__("mtdec %0" : : "r" (0));
/* Enable interrupts! */
_enable();
}
VOID
NTAPI
KiInitializePcr(IN ULONG ProcessorNumber,
IN PKIPCR Pcr,
IN PKTHREAD IdleThread,
IN PVOID DpcStack)
{
Pcr->MajorVersion = PCR_MAJOR_VERSION;
Pcr->MinorVersion = PCR_MINOR_VERSION;
Pcr->CurrentIrql = PASSIVE_LEVEL;
Pcr->PrcbData = &PrcbData[ProcessorNumber];
Pcr->PrcbData->MajorVersion = PRCB_MAJOR_VERSION;
Pcr->PrcbData->MinorVersion = 0;
Pcr->PrcbData->Number = 0; /* UP for now */
Pcr->PrcbData->SetMember = 1;
#if DBG
Pcr->PrcbData->BuildType = PRCB_BUILD_DEBUG;
#else
Pcr->PrcbData->BuildType = 0;
#endif
Pcr->PrcbData->DpcStack = DpcStack;
KeGetPcr()->Prcb = Pcr->PrcbData;
KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
}
extern ULONG KiGetFeatureBits();
extern VOID KiSetProcessorType();
extern VOID KiGetCacheInformation();
VOID
NTAPI
KiInitializeKernel(IN PKPROCESS InitProcess,
IN PKTHREAD InitThread,
IN PVOID IdleStack,
IN PKPRCB Prcb,
IN CCHAR Number,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG FeatureBits;
LARGE_INTEGER PageDirectory;
PVOID DpcStack;
/* Detect and set the CPU Type */
KiSetProcessorType();
/* Initialize the Power Management Support for this PRCB */
PoInitializePrcb(Prcb);
/* Get the processor features for the CPU */
FeatureBits = KiGetFeatureBits();
/* Save feature bits */
Prcb->FeatureBits = FeatureBits;
/* Get cache line information for this CPU */
KiGetCacheInformation();
/* Initialize spinlocks and DPC data */
KiInitSpinLocks(Prcb, Number);
/* Check if this is the Boot CPU */
if (!Number)
{
/* Set Node Data */
KeNodeBlock[0] = &KiNode0;
Prcb->ParentNode = KeNodeBlock[0];
KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
/* Set boot-level flags */
KeProcessorArchitecture = 0;
KeProcessorLevel = (USHORT)Prcb->CpuType;
KeFeatureBits = FeatureBits;
/* Set the current MP Master KPRCB to the Boot PRCB */
Prcb->MultiThreadSetMaster = Prcb;
/* Lower to APC_LEVEL */
KeLowerIrql(APC_LEVEL);
/* Initialize portable parts of the OS */
KiInitSystem();
/* Initialize the Idle Process and the Process Listhead */
InitializeListHead(&KiProcessListHead);
PageDirectory.QuadPart = 0;
KeInitializeProcess(InitProcess,
0,
0xFFFFFFFF,
&PageDirectory,
TRUE);
InitProcess->QuantumReset = MAXCHAR;
}
else
{
/* FIXME */
DPRINT1("SMP Boot support not yet present\n");
}
/* Setup the Idle Thread */
KeInitializeThread(InitProcess,
InitThread,
NULL,
NULL,
NULL,
NULL,
NULL,
IdleStack);
InitThread->NextProcessor = Number;
InitThread->Priority = HIGH_PRIORITY;
InitThread->State = Running;
InitThread->Affinity = 1 << Number;
InitThread->WaitIrql = DISPATCH_LEVEL;
InitProcess->ActiveProcessors = 1 << Number;
/* HACK for MmUpdatePageDir */
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
/* Set up the thread-related fields in the PRCB */
Prcb->CurrentThread = InitThread;
Prcb->NextThread = NULL;
Prcb->IdleThread = InitThread;
/* Initialize Kernel Memory Address Space */
MmInit1(MmFreeLdrFirstKrnlPhysAddr,
MmFreeLdrLastKrnlPhysAddr,
MmFreeLdrLastKernelAddress,
KeMemoryMap,
KeMemoryMapRangeCount,
4096);
/* Initialize the Kernel Executive */
ExpInitializeExecutive(0, LoaderBlock);
/* Only do this on the boot CPU */
if (!Number)
{
/* Calculate the time reciprocal */
KiTimeIncrementReciprocal =
KiComputeReciprocal(KeMaximumIncrement,
&KiTimeIncrementShiftCount);
/* Update DPC Values in case they got updated by the executive */
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
Prcb->MinimumDpcRate = KiMinimumDpcRate;
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
/* Allocate the DPC Stack */
DpcStack = MmCreateKernelStack(FALSE, 0);
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
Prcb->DpcStack = DpcStack;
}
KfRaiseIrql(DISPATCH_LEVEL);
KeSetPriorityThread(InitThread, 0);
/* Setup decrementer exception */
KiSetupDecrementerTrap();
KfLowerIrql(PASSIVE_LEVEL);
/* Should not return */
while(1)
{
NtYieldExecution();
}
}
extern int KiPageFaultTrap();
KTRAP_FRAME KiInitialTrapFrame;
/* Use this for early boot additions to the page table */
VOID
NTAPI
KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG Cpu;
ppc_map_info_t info[4];
PKIPCR Pcr = (PKIPCR)KPCR_BASE;
PKPRCB Prcb;
__asm__("mr 13,%0" : : "r" (KPCR_BASE));
/* Set the page fault handler to the kernel */
MmuSetTrapHandler(3,KiPageFaultTrap);
MmuSetTrapHandler(4,KiPageFaultTrap);
// Make 0xf... special
MmuAllocVsid(2, 0x8000);
MmuSetVsid(15,16,2);
/* Get the current CPU */
Cpu = KeNumberProcessors;
if (!Cpu)
{
/* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
* change when we get SMP support.
*/
info[0].phys = 0;
info[0].proc = 2;
info[0].addr = (vaddr_t)Pcr;
info[0].flags = MMU_KRW_UR;
info[1].phys = 0;
info[1].proc = 2;
info[1].addr = ((vaddr_t)Pcr) + (1 << PAGE_SHIFT);
info[1].flags = MMU_KRW_UR;
info[2].phys = 0;
info[2].proc = 2;
info[2].addr = (vaddr_t)KI_USER_SHARED_DATA;
info[2].flags = MMU_KRW_UR;
info[3].phys = 0;
info[3].proc = 2;
info[3].addr = (vaddr_t)KIP0PCRADDRESS;
info[3].flags = MMU_KRW_UR;
MmuMapPage(info, 4);
}
/* Skip initial setup if this isn't the Boot CPU */
if (Cpu) goto AppCpuInit;
/* Initialize the PCR */
RtlZeroMemory(Pcr, PAGE_SIZE);
KiInitializePcr(Cpu,
Pcr,
&KiInitialThread.Tcb,
KiDoubleFaultStack);
/* Set us as the current process */
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
KiInitialThread.Tcb.TrapFrame = &KiInitialTrapFrame;
/* Setup CPU-related fields */
AppCpuInit:
Pcr->Number = Cpu;
Pcr->SetMember = 1 << Cpu;
Prcb = KeGetCurrentPrcb();
Prcb->SetMember = 1 << Cpu;
/* Initialize the Processor with HAL */
HalInitializeProcessor(Cpu, LoaderBlock);
/* Set active processors */
KeActiveProcessors |= Pcr->SetMember;
KeNumberProcessors++;
/* Initialize the Debugger for the Boot CPU */
if (!Cpu) KdInitSystem (0, LoaderBlock);
/* Check for break-in */
if (KdPollBreakIn())
{
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
}
/* Raise to HIGH_LEVEL */
KfRaiseIrql(HIGH_LEVEL);
/* Call main kernel intialization */
KiInitializeKernel(&KiInitialProcess.Pcb,
&KiInitialThread.Tcb,
P0BootStack,
Prcb,
Cpu,
(PVOID)LoaderBlock);
}
VOID
NTAPI
KiInitMachineDependent(VOID)
{
}
void abort(VOID)
{
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
while(1);
}

View file

@ -1,76 +0,0 @@
#include <ndk/asm.h>
#define AP_MAGIC (0x12481020)
.global P0BootStack
.global KiDoubleFaultStack
.global _kernel_stack
.global _kernel_stack_top
.global _kernel_trap_stack
.global _kernel_trap_stack_top
.section .bss
.align 12
/* guard page for the kernel stack */
.fill 4096, 1, 0
_kernel_stack:
.fill 3*4096, 1, 0
P0BootStack:
_kernel_stack_top:
/* guard page for the trap stack */
.fill 4096, 1, 0
_kernel_trap_stack:
.fill 3*4096, 1, 0
_kernel_trap_stack_top:
.fill 3*4096, 1, 0
KiDoubleFaultStack:
.text
.globl KiSystemStartup
.globl KiRosPrepareForSystemStartup
.globl DrawNumber
KiSystemStartup:
/*
* Set a normal MSR value
*/
xor 0,0,0
ori 30,0,0x3030
mtmsr 30
/*
* Reserve space for the floating point save area.
*/
addi 1,1,-SIZEOF_FX_SAVE_AREA
/* Bye bye asm land! */
mr 4,3
/* Load the initial kernel stack */
lis 1,_kernel_stack_top@ha
ori 1,1,_kernel_stack_top@l
addi 1,1,-SIZEOF_FX_SAVE_AREA
/* Call the main kernel initialization */
bl KiRosPrepareForSystemStartup
.global NtCurrentTeb
NtCurrentTeb:
mr 3,12
blr
.globl KeSynchronizeExecution
KeSynchronizeExecution:
blr
.globl PearPCDebug
PearPCDebug:
// .long 0x00333303
blr

View file

@ -1,805 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/powerpc/ppc_irq.c
* PURPOSE: IRQ handling
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/*
* NOTE: In general the PIC interrupt priority facilities are used to
* preserve the NT IRQL semantics, global interrupt disables are only used
* to keep the PIC in a consistent state
*
*/
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#include <ppcmmu/mmu.h>
#define NDEBUG
#include <debug.h>
KDPC KiExpireTimerDpc;
extern ULONG KiMaximumDpcQueueDepth;
extern ULONG KiMinimumDpcRate;
extern ULONG KiAdjustDpcThreshold;
extern ULONG KiIdealDpcRate;
extern LONG KiTickOffset;
extern ULONG KeMaximumIncrement;
extern ULONG KeMinimumIncrement;
extern ULONG KeTimeAdjustment;
extern void PearPCDebug(int ch);
/* GLOBALS *****************************************************************/
/* Interrupt handler list */
#define NR_TRAPS 16
#ifdef CONFIG_SMP
#define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum
#define BUILD_INTERRUPT_HANDLER(intnum) \
VOID INT_NAME2(intnum)(VOID);
#define D(x,y) \
BUILD_INTERRUPT_HANDLER(x##y)
#define D16(x) \
D(x,0) D(x,1) D(x,2) D(x,3) \
D(x,4) D(x,5) D(x,6) D(x,7) \
D(x,8) D(x,9) D(x,A) D(x,B) \
D(x,C) D(x,D) D(x,E) D(x,F)
D16(3) D16(4) D16(5) D16(6)
D16(7) D16(8) D16(9) D16(A)
D16(B) D16(C) D16(D) D16(E)
D16(F)
#define L(x,y) \
(ULONG)& INT_NAME2(x##y)
#define L16(x) \
L(x,0), L(x,1), L(x,2), L(x,3), \
L(x,4), L(x,5), L(x,6), L(x,7), \
L(x,8), L(x,9), L(x,A), L(x,B), \
L(x,C), L(x,D), L(x,E), L(x,F)
static ULONG irq_handler[ROUND_UP(NR_TRAPS, 16)] = {
L16(3), L16(4), L16(5), L16(6),
L16(7), L16(8), L16(9), L16(A),
L16(B), L16(C), L16(D), L16(E)
};
#undef L
#undef L16
#undef D
#undef D16
#else /* CONFIG_SMP */
void trap_handler_0(void);
void trap_handler_1(void);
void trap_handler_2(void);
void trap_handler_3(void);
void trap_handler_4(void);
void trap_handler_5(void);
void trap_handler_6(void);
void trap_handler_7(void);
void trap_handler_8(void);
void trap_handler_9(void);
void trap_handler_10(void);
void trap_handler_11(void);
void trap_handler_12(void);
void trap_handler_13(void);
void trap_handler_14(void);
void trap_handler_15(void);
static unsigned int trap_handler[NR_TRAPS] __attribute__((unused)) =
{
(int)&trap_handler_0,
(int)&trap_handler_1,
(int)&trap_handler_2,
(int)&trap_handler_3,
(int)&trap_handler_4,
(int)&trap_handler_5,
(int)&trap_handler_6,
(int)&trap_handler_7,
(int)&trap_handler_8,
(int)&trap_handler_9,
(int)&trap_handler_10,
(int)&trap_handler_11,
(int)&trap_handler_12,
(int)&trap_handler_13,
(int)&trap_handler_14,
(int)&trap_handler_15,
};
#endif /* CONFIG_SMP */
/*
* PURPOSE: Object describing each isr
* NOTE: The data in this table is only modified at passsive level but can
* be accessed at any irq level.
*/
typedef struct
{
LIST_ENTRY ListHead;
KSPIN_LOCK Lock;
ULONG Count;
}
ISR_TABLE, *PISR_TABLE;
#ifdef CONFIG_SMP
static ISR_TABLE IsrTable[NR_TRAPS][MAXIMUM_PROCESSORS];
#else
static ISR_TABLE IsrTable[NR_TRAPS][1];
#endif
#define TAG_ISR_LOCK 'LRSI'
/* FUNCTIONS ****************************************************************/
CODE_SEG("INIT")
VOID
NTAPI
KeInitInterrupts (VOID)
{
int i, j;
/*
* Setup the IDT entries to point to the interrupt handlers
*/
for (i=0;i<NR_TRAPS;i++)
{
#ifdef CONFIG_SMP
for (j = 0; j < MAXIMUM_PROCESSORS; j++)
#else
j = 0;
#endif
{
InitializeListHead(&IsrTable[i][j].ListHead);
KeInitializeSpinLock(&IsrTable[i][j].Lock);
IsrTable[i][j].Count = 0;
}
}
}
static VOID
KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
PKTRAP_FRAME TrapFrame)
{
}
static VOID
KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame,
PKIRQ_TRAPFRAME IrqTrapFrame)
{
}
/*
* NOTE: On Windows this function takes exactly one parameter and EBP is
* guaranteed to point to KTRAP_FRAME. The function is used only
* by HAL, so there's no point in keeping that prototype.
*
* @implemented
*/
VOID
NTAPI
KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
IN KIRQL Irql)
{
PKPRCB Prcb = KeGetCurrentPrcb();
PKTHREAD CurrentThread;
PKPROCESS CurrentProcess;
/* Make sure we don't go further if we're in early boot phase. */
if (!(Prcb) || !(Prcb->CurrentThread)) return;
/* Get the current thread and process */
CurrentThread = Prcb->CurrentThread;
CurrentProcess = CurrentThread->ApcState.Process;
/* Check if we came from user mode */
if (TrapFrame->PreviousMode != KernelMode)
{
/* Update user times */
CurrentThread->UserTime++;
InterlockedIncrement((PLONG)&CurrentProcess->UserTime);
Prcb->UserTime++;
}
else
{
/* Check IRQ */
if (Irql > DISPATCH_LEVEL)
{
/* This was an interrupt */
Prcb->InterruptTime++;
}
else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive))
{
/* This was normal kernel time */
CurrentThread->KernelTime++;
InterlockedIncrement((PLONG)&CurrentProcess->KernelTime);
}
else if (Irql == DISPATCH_LEVEL)
{
/* This was DPC time */
Prcb->DpcTime++;
}
/* Update CPU kernel time in all cases */
Prcb->KernelTime++;
}
/* Set the last DPC Count and request rate */
Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
Prcb->DpcRequestRate) / 2;
/* Check if we should request a DPC */
if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
{
/* Request one */
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
/* Update the depth if needed */
if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
(Prcb->MaximumDpcQueueDepth > 1))
{
/* Decrease the maximum depth by one */
Prcb->MaximumDpcQueueDepth--;
}
}
else
{
/* Decrease the adjustment threshold */
if (!(--Prcb->AdjustDpcThreshold))
{
/* We've hit 0, reset it */
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
/* Check if we've hit queue maximum */
if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
{
/* Increase maximum by one */
Prcb->MaximumDpcQueueDepth++;
}
}
}
/*
* If we're at end of quantum request software interrupt. The rest
* is handled in KiDispatchInterrupt.
*
* NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine
* which checks for quantum end will not be executed and decrementing
* the quantum here can result in overflow. This is not a problem since
* we don't care about the quantum value anymore after the QuantumEnd
* flag is set.
*/
if ((CurrentThread->Quantum -= 3) <= 0)
{
Prcb->QuantumEnd = TRUE;
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
}
}
/*
* NOTE: On Windows this function takes exactly zero parameters and EBP is
* guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL.
* The function is used only by HAL, so there's no point in keeping
* that prototype.
*
* @implemented
*/
VOID
NTAPI
KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
IN KIRQL Irql,
IN ULONG Increment)
{
LONG OldOffset;
LARGE_INTEGER Time;
ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
/* Update interrupt time */
Time.LowPart = SharedUserData->InterruptTime.LowPart;
Time.HighPart = SharedUserData->InterruptTime.High1Time;
Time.QuadPart += Increment;
SharedUserData->InterruptTime.High2Time = Time.u.HighPart;
SharedUserData->InterruptTime.LowPart = Time.u.LowPart;
SharedUserData->InterruptTime.High1Time = Time.u.HighPart;
/* Increase the tick offset */
KiTickOffset -= Increment;
OldOffset = KiTickOffset;
/* Check if this isn't a tick yet */
if (KiTickOffset > 0)
{
/* Expire timers */
KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
}
else
{
/* Setup time structure for system time */
Time.LowPart = SharedUserData->SystemTime.LowPart;
Time.HighPart = SharedUserData->SystemTime.High1Time;
Time.QuadPart += KeTimeAdjustment;
SharedUserData->SystemTime.High2Time = Time.HighPart;
SharedUserData->SystemTime.LowPart = Time.LowPart;
SharedUserData->SystemTime.High1Time = Time.HighPart;
/* Setup time structure for tick time */
Time.LowPart = KeTickCount.LowPart;
Time.HighPart = KeTickCount.High1Time;
Time.QuadPart += 1;
KeTickCount.High2Time = Time.HighPart;
KeTickCount.LowPart = Time.LowPart;
KeTickCount.High1Time = Time.HighPart;
SharedUserData->TickCount.High2Time = Time.HighPart;
SharedUserData->TickCount.LowPart = Time.LowPart;
SharedUserData->TickCount.High1Time = Time.HighPart;
/* Queue a DPC that will expire timers */
KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
}
/* Update process and thread times */
if (OldOffset <= 0)
{
/* This was a tick, calculate the next one */
KiTickOffset += KeMaximumIncrement;
KeUpdateRunTime(TrapFrame, Irql);
}
}
VOID NTAPI
KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
/*
* FUNCTION: Calls all the interrupt handlers for a given irq.
* ARGUMENTS:
* vector - The number of the vector to call handlers for.
* old_level - The irql of the processor when the irq took place.
* NOTES: Must be called at DIRQL.
*/
{
PKINTERRUPT isr;
PLIST_ENTRY current;
KIRQL oldlvl;
PISR_TABLE CurrentIsr;
DPRINT("I(0x%.08x, 0x%.08x)\n", vector, old_level);
/*
* Iterate the list until one of the isr tells us its device interrupted
*/
CurrentIsr = &IsrTable[vector][(ULONG)KeGetCurrentProcessorNumber()];
KiAcquireSpinLock(&CurrentIsr->Lock);
CurrentIsr->Count++;
current = CurrentIsr->ListHead.Flink;
while (current != &CurrentIsr->ListHead)
{
isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
oldlvl = KeAcquireInterruptSpinLock(isr);
if (isr->ServiceRoutine(isr, isr->ServiceContext))
{
KeReleaseInterruptSpinLock(isr, oldlvl);
break;
}
KeReleaseInterruptSpinLock(isr, oldlvl);
current = current->Flink;
}
KiReleaseSpinLock(&CurrentIsr->Lock);
}
VOID
KiInterruptDispatch3 (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
/*
* FUNCTION: Calls the irq specific handler for an irq
* ARGUMENTS:
* irq = IRQ that has interrupted
*/
{
KIRQL old_level;
KTRAP_FRAME KernelTrapFrame;
PKTHREAD CurrentThread;
PKTRAP_FRAME OldTrapFrame=NULL;
/*
* At this point we have interrupts disabled, nothing has been done to
* the PIC.
*/
KeGetCurrentPrcb()->InterruptCount++;
/*
* Notify the rest of the kernel of the raised irq level. For the
* default HAL this will send an EOI to the PIC and alter the IRQL.
*/
if (!HalBeginSystemInterrupt (vector,
vector,
&old_level))
{
return;
}
/*
* Enable interrupts
* NOTE: Only higher priority interrupts will get through
*/
_enable();
#ifndef CONFIG_SMP
if (vector == 0)
{
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
}
else
#endif
{
/*
* Actually call the ISR.
*/
KiInterruptDispatch2(vector, old_level);
}
/*
* End the system interrupt.
*/
_disable();
if (old_level==PASSIVE_LEVEL)
{
HalEndSystemInterrupt (APC_LEVEL, 0);
CurrentThread = KeGetCurrentThread();
if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending)
{
if (CurrentThread->TrapFrame == NULL)
{
OldTrapFrame = CurrentThread->TrapFrame;
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
CurrentThread->TrapFrame = &KernelTrapFrame;
}
_enable();
KiDeliverApc(UserMode, NULL, NULL);
_disable();
ASSERT(KeGetCurrentThread() == CurrentThread);
if (CurrentThread->TrapFrame == &KernelTrapFrame)
{
KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe);
CurrentThread->TrapFrame = OldTrapFrame;
}
}
KeLowerIrql(PASSIVE_LEVEL);
}
else
{
HalEndSystemInterrupt (old_level, 0);
}
}
static VOID
KeDumpIrqList(VOID)
{
PKINTERRUPT current;
PLIST_ENTRY current_entry;
LONG i, j;
KIRQL oldlvl;
BOOLEAN printed;
for (i=0;i<NR_TRAPS;i++)
{
printed = FALSE;
KeRaiseIrql(i,&oldlvl);
for (j=0; j < KeNumberProcessors; j++)
{
KiAcquireSpinLock(&IsrTable[i][j].Lock);
current_entry = IsrTable[i][j].ListHead.Flink;
current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
while (current_entry!=&(IsrTable[i][j].ListHead))
{
if (printed == FALSE)
{
printed = TRUE;
DPRINT("For irq %x:\n",i);
}
DPRINT(" Isr %x\n",current);
current_entry = current_entry->Flink;
current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
}
KiReleaseSpinLock(&IsrTable[i][j].Lock);
}
KeLowerIrql(oldlvl);
}
}
/*
* @implemented
*/
BOOLEAN
NTAPI
KeConnectInterrupt(PKINTERRUPT InterruptObject)
{
KIRQL oldlvl,synch_oldlvl;
PKINTERRUPT ListHead;
ULONG Vector;
PISR_TABLE CurrentIsr;
BOOLEAN Result;
DPRINT("KeConnectInterrupt()\n");
Vector = InterruptObject->Vector;
if (Vector < 0 || Vector >= NR_TRAPS)
return FALSE;
ASSERT (InterruptObject->Number < KeNumberProcessors);
KeSetSystemAffinityThread(1 << InterruptObject->Number);
CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->Number];
KeRaiseIrql(Vector,&oldlvl);
KiAcquireSpinLock(&CurrentIsr->Lock);
/*
* Check if the vector is already in use that we can share it
*/
if (!IsListEmpty(&CurrentIsr->ListHead))
{
ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
{
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
KeRevertToUserAffinityThread();
return FALSE;
}
}
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
DPRINT("%x %x\n",CurrentIsr->ListHead.Flink, CurrentIsr->ListHead.Blink);
Result = HalEnableSystemInterrupt(Vector, InterruptObject->Irql, InterruptObject->Mode);
if (Result)
{
InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->InterruptListEntry.Blink);
}
InterruptObject->Connected = TRUE;
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
/*
* Release the table spinlock
*/
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
KeDumpIrqList();
KeRevertToUserAffinityThread();
return Result;
}
/*
* @implemented
*
* FUNCTION: Releases a drivers isr
* ARGUMENTS:
* InterruptObject = isr to release
*/
BOOLEAN
NTAPI
KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
{
KIRQL oldlvl,synch_oldlvl;
PISR_TABLE CurrentIsr;
BOOLEAN State;
DPRINT1("KeDisconnectInterrupt\n");
ASSERT (InterruptObject->Number < KeNumberProcessors);
/* Set the affinity */
KeSetSystemAffinityThread(1 << InterruptObject->Number);
/* Get the ISR Tabe */
CurrentIsr = &IsrTable[InterruptObject->Vector]
[(ULONG)InterruptObject->Number];
/* Raise IRQL to required level and lock table */
KeRaiseIrql(InterruptObject->Vector,&oldlvl);
KiAcquireSpinLock(&CurrentIsr->Lock);
/* Check if it's actually connected */
if ((State = InterruptObject->Connected))
{
/* Lock the Interrupt */
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
/* Remove this one, and check if all are gone */
RemoveEntryList(&InterruptObject->InterruptListEntry);
if (IsListEmpty(&CurrentIsr->ListHead))
{
/* Completely Disable the Interrupt */
HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql);
}
/* Disconnect it */
InterruptObject->Connected = FALSE;
/* Release the interrupt lock */
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
}
/* Release the table spinlock */
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
/* Go back to default affinity */
KeRevertToUserAffinityThread();
/* Return Old Interrupt State */
return State;
}
/*
* @implemented
*/
VOID
NTAPI
KeInitializeInterrupt(PKINTERRUPT Interrupt,
PKSERVICE_ROUTINE ServiceRoutine,
PVOID ServiceContext,
PKSPIN_LOCK SpinLock,
ULONG Vector,
KIRQL Irql,
KIRQL SynchronizeIrql,
KINTERRUPT_MODE InterruptMode,
BOOLEAN ShareVector,
CHAR ProcessorNumber,
BOOLEAN FloatingSave)
{
/* Set the Interrupt Header */
Interrupt->Type = InterruptObject;
Interrupt->Size = sizeof(KINTERRUPT);
/* Check if we got a spinlock */
if (SpinLock)
{
Interrupt->ActualLock = SpinLock;
}
else
{
/* This means we'll be usin the built-in one */
KeInitializeSpinLock(&Interrupt->SpinLock);
Interrupt->ActualLock = &Interrupt->SpinLock;
}
/* Set the other settings */
Interrupt->ServiceRoutine = ServiceRoutine;
Interrupt->ServiceContext = ServiceContext;
Interrupt->Vector = Vector;
Interrupt->Irql = Irql;
Interrupt->SynchronizeIrql = SynchronizeIrql;
Interrupt->Mode = InterruptMode;
Interrupt->ShareVector = ShareVector;
Interrupt->Number = ProcessorNumber;
Interrupt->FloatingSave = FloatingSave;
/* Disconnect it at first */
Interrupt->Connected = FALSE;
}
VOID KePrintInterruptStatistic(VOID)
{
LONG i, j;
for (j = 0; j < KeNumberProcessors; j++)
{
DPRINT1("CPU%d:\n", j);
for (i = 0; i < NR_TRAPS; i++)
{
if (IsrTable[i][j].Count)
{
DPRINT1(" Irq %x(%d): %d\n", i, i, IsrTable[i][j].Count);
}
}
}
}
BOOLEAN
NTAPI
KeDisableInterrupts(VOID)
{
ULONG Flags = 0;
BOOLEAN Return;
Flags = __readmsr();
Return = (Flags & 0x8000) ? TRUE: FALSE;
/* Disable interrupts */
_disable();
return Return;
}
ULONG
NTAPI
KdpServiceDispatcher(ULONG Service,
PVOID Buffer1,
ULONG Buffer1Length,
KPROCESSOR_MODE PreviousMode);
typedef ULONG (*PSYSCALL_FUN)
(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
VOID
NTAPI
KiSystemService(ppc_trap_frame_t *trap_frame)
{
int i;
PKSYSTEM_ROUTINE SystemRoutine;
PSYSCALL_FUN SyscallFunction;
switch(trap_frame->gpr[0])
{
case 0x10000: /* DebugService */
for( i = 0; i < trap_frame->gpr[5]; i++ )
{
PearPCDebug(((PCHAR)trap_frame->gpr[4])[i]);
WRITE_PORT_UCHAR((PVOID)0x800003f8, ((PCHAR)trap_frame->gpr[4])[i]);
}
trap_frame->gpr[3] = KdpServiceDispatcher
(trap_frame->gpr[3],
(PCHAR)trap_frame->gpr[4],
trap_frame->gpr[5],
UserMode /*KernelMode*/);
break;
case 0xf0000: /* Thread startup */
/* XXX how to use UserThread (gpr[6]) */
SystemRoutine = (PKSYSTEM_ROUTINE)trap_frame->gpr[3];
SystemRoutine((PKSTART_ROUTINE)trap_frame->gpr[4],
(PVOID)trap_frame->gpr[5]);
break;
/* Handle a normal system call */
default:
SyscallFunction =
((PSYSCALL_FUN*)KeServiceDescriptorTable
[trap_frame->gpr[0] >> 12].Base)[trap_frame->gpr[0] & 0xfff];
trap_frame->gpr[3] = SyscallFunction
(trap_frame->gpr[3],
trap_frame->gpr[4],
trap_frame->gpr[5],
trap_frame->gpr[6],
trap_frame->gpr[7],
trap_frame->gpr[8],
trap_frame->gpr[9],
trap_frame->gpr[10],
trap_frame->gpr[11],
trap_frame->gpr[12]);
break;
}
}
/* EOF */

View file

@ -1,222 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/powerpc/stubs.c
* PURPOSE: VDM Support Services
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
NTSTATUS
NTAPI
NtVdmControl(IN ULONG ControlCode,
IN PVOID ControlData)
{
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
Ke386CallBios(IN ULONG Int,
OUT PCONTEXT Context)
{
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
KiUnexpectedInterrupt(VOID)
{
}
LONG NTAPI Exi386InterlockedDecrementLong(PLONG Addend)
{
return _InterlockedDecrement(Addend);
}
LONG NTAPI Exi386InterlockedIncrementLong(PLONG Addend)
{
return _InterlockedIncrement(Addend);
}
LONG NTAPI Exi386InterlockedExchangeUlong(PLONG Target, LONG Exch, LONG Compare)
{
return _InterlockedCompareExchange(Target, Exch, Compare);
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
KeI386FlatToGdtSelector(IN ULONG Base,
IN USHORT Length,
IN USHORT Selector)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
KeI386ReleaseGdtSelectors(OUT PULONG SelArray,
IN ULONG NumOfSelectors)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
KeI386AllocateGdtSelectors(OUT PULONG SelArray,
IN ULONG NumOfSelectors)
{
UNIMPLEMENTED;
return 0;
}
VOID
NTAPI
KeDumpStackFrames(PULONG Frame)
{
}
LONG
NTAPI
Kei386EoiHelper() { return 0; }
NTSTATUS
NTAPI
KeUserModeCallback(IN ULONG RoutineIndex,
IN PVOID Argument,
IN ULONG ArgumentLength,
OUT PVOID *Result,
OUT PULONG ResultLength)
{
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
KiCoprocessorError() { }
VOID
NTAPI
KiDispatchInterrupt() { }
VOID
NTAPI
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame,
IN PKNORMAL_ROUTINE NormalRoutine,
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
}
PVOID
NTAPI
KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit)
{
return NULL;
}
VOID
NTAPI
KiSwapProcess(struct _KPROCESS *NewProcess, struct _KPROCESS *OldProcess)
{
PEPROCESS EProcess = (PEPROCESS)NewProcess;
MmuSetVsid(0, 8, EProcess ? (ULONG)EProcess->UniqueProcessId : 0);
}
BOOLEAN
NTAPI
KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
{
KeGetPcr()->Prcb->NextThread = NewThread;
__asm__("mtdec %0" : : "r" (1));
return TRUE;
}
VOID
NTAPI
KeI386VdmInitialize(VOID)
{
}
NTSYSAPI
NTSTATUS
NTAPI
NtCallbackReturn
( IN PVOID Result OPTIONAL, IN ULONG ResultLength, IN NTSTATUS Status )
{
return STATUS_UNSUCCESSFUL;
}
NTSYSAPI
NTSTATUS
NTAPI
NtContinue
(IN PCONTEXT ThreadContext, IN BOOLEAN RaiseAlert)
{
return STATUS_UNSUCCESSFUL;
}
NTSYSAPI
ULONG
NTAPI
NtGetTickCount() { return __rdtsc(); }
NTSTATUS
NTAPI
NtSetLdtEntries
(ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
{
return STATUS_UNSUCCESSFUL;
}
NTSYSAPI
NTSTATUS
NTAPI
NtRaiseException
(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ThreadContext, IN BOOLEAN HandleException )
{
return STATUS_UNSUCCESSFUL;
}
void _alldiv() { }
void _alldvrm() { }
void _allmul() { }
void _alloca_probe() { }
void _allrem() { }
void _allshl() { }
void _allshr() { }
void _aulldiv() { }
void _aulldvrm() { }
void _aullrem() { }
void _aullshr() { }
void _abnormal_termination() { }

View file

@ -1,20 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/powerpc/systimer.c
* PURPOSE: Kernel Initialization for x86 CPUs
* PROGRAMMERS: Art Yerkes (ayerkes@speakeasy.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
ULONG
NTAPI
KiComputeTimerTableIndex(LONGLONG Timer)
{
return 0; // XXX arty fixme
}

View file

@ -1,222 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/powerpc/thrdini.c
* PURPOSE: i386 Thread Context Creation
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
* arty (ppc adaptation)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
//#define NDEBUG
#include <debug.h>
#include <ndk/powerpc/ketypes.h>
#include <ppcmmu/mmu.h>
typedef struct _KSWITCHFRAME
{
PVOID ExceptionList;
BOOLEAN ApcBypassDisable;
PVOID RetAddr;
} KSWITCHFRAME, *PKSWITCHFRAME;
typedef struct _KSTART_FRAME
{
PKSYSTEM_ROUTINE SystemRoutine;
PKSTART_ROUTINE StartRoutine;
PVOID StartContext;
BOOLEAN UserThread;
} KSTART_FRAME, *PKSTART_FRAME;
typedef struct _KUINIT_FRAME
{
KSWITCHFRAME CtxSwitchFrame;
KSTART_FRAME StartFrame;
KTRAP_FRAME TrapFrame;
FX_SAVE_AREA FxSaveArea;
} KUINIT_FRAME, *PKUINIT_FRAME;
typedef struct _KKINIT_FRAME
{
KSWITCHFRAME CtxSwitchFrame;
KSTART_FRAME StartFrame;
KTRAP_FRAME TrapFrame;
FX_SAVE_AREA FxSaveArea;
} KKINIT_FRAME, *PKKINIT_FRAME;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
KiInitializeContextThread(IN PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext,
IN PCONTEXT ContextPointer)
{
PFX_SAVE_AREA FxSaveArea;
PKSTART_FRAME StartFrame;
PKSWITCHFRAME CtxSwitchFrame;
PKTRAP_FRAME TrapFrame;
CONTEXT LocalContext;
PCONTEXT Context = NULL;
ppc_map_info_t pagemap[16];
PETHREAD EThread = (PETHREAD)Thread;
PEPROCESS Process = EThread->ThreadsProcess;
ULONG ContextFlags, i, pmsize = sizeof(pagemap) / sizeof(pagemap[0]);
DPRINT("Thread: %08x ContextPointer: %08x SystemRoutine: %08x StartRoutine: %08x StartContext: %08x\n",
Thread,
ContextPointer,
SystemRoutine,
StartRoutine,
StartContext);
/* Check if this is a With-Context Thread */
if (ContextPointer)
{
/* Set up the Initial Frame */
PKUINIT_FRAME InitFrame;
InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
sizeof(KUINIT_FRAME));
/* Copy over the context we got */
RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
Context = &LocalContext;
ContextFlags = CONTEXT_CONTROL;
/* Zero out the trap frame and save area */
RtlZeroMemory(&InitFrame->TrapFrame,
KTRAP_FRAME_LENGTH + sizeof(FX_SAVE_AREA));
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
/* Disable any debug regiseters */
Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
/* Setup the Trap Frame */
TrapFrame = &InitFrame->TrapFrame;
/* Set up a trap frame from the context. */
KeContextToTrapFrame(Context,
NULL,
TrapFrame,
Context->ContextFlags | ContextFlags,
UserMode);
/* Set the previous mode as user */
TrapFrame->PreviousMode = UserMode;
/* Terminate the Exception Handler List */
RtlZeroMemory(TrapFrame->ExceptionRecord, sizeof(TrapFrame->ExceptionRecord));
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
/* Tell the thread it will run in User Mode */
Thread->PreviousMode = UserMode;
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = TRUE;
Thread->TrapFrame = TrapFrame;
DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
Thread,
TrapFrame->Iar,
TrapFrame->Msr,
TrapFrame->Gpr1,
TrapFrame->Gpr3);
}
else
{
/* Set up the Initial Frame for the system thread */
PKKINIT_FRAME InitFrame;
InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
sizeof(KKINIT_FRAME));
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
/* Tell the thread it will run in Kernel Mode */
Thread->PreviousMode = KernelMode;
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = FALSE;
/* Setup the Trap Frame */
TrapFrame = &InitFrame->TrapFrame;
Thread->TrapFrame = TrapFrame;
TrapFrame->OldIrql = PASSIVE_LEVEL;
TrapFrame->Iar = (ULONG)SystemRoutine;
TrapFrame->Msr = 0xb030;
TrapFrame->Gpr1 = ((ULONG)&InitFrame->StartFrame) - 0x200;
TrapFrame->Gpr3 = (ULONG)StartRoutine;
TrapFrame->Gpr4 = (ULONG)StartContext;
__asm__("mr %0,13" : "=r" (((PULONG)&TrapFrame->Gpr0)[13]));
DPRINT("Thread %08x Iar %08x Msr %08x Gpr1 %08x Gpr3 %08x\n",
Thread,
TrapFrame->Iar,
TrapFrame->Msr,
TrapFrame->Gpr1,
TrapFrame->Gpr3);
}
/* Now setup the remaining data for KiThreadStartup */
StartFrame->StartContext = StartContext;
StartFrame->StartRoutine = StartRoutine;
StartFrame->SystemRoutine = SystemRoutine;
/* And set up the Context Switch Frame */
CtxSwitchFrame->RetAddr = KiThreadStartup;
CtxSwitchFrame->ApcBypassDisable = TRUE;
CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;
/* Save back the new value of the kernel stack. */
Thread->KernelStack = (PVOID)CtxSwitchFrame;
/* If we're the first thread of the new process, copy the top 16 pages
* from process 0 */
if (Process && IsListEmpty(&Process->ThreadListHead))
{
DPRINT("First Thread in Process %x\n", Process);
MmuAllocVsid((ULONG)Process->UniqueProcessId, 0xff);
for (i = 0; i < pmsize; i++)
{
pagemap[i].proc = 0;
pagemap[i].addr = 0x7fff0000 + (i * PAGE_SIZE);
}
MmuInqPage(pagemap, pmsize);
for (i = 0; i < pmsize; i++)
{
if (pagemap[i].phys)
{
pagemap[i].proc = (ULONG)Process->UniqueProcessId;
pagemap[i].phys = 0;
MmuMapPage(&pagemap[i], 1);
DPRINT("Added map to the new process: P %08x A %08x\n",
pagemap[i].proc, pagemap[i].addr);
}
}
DPRINT("Did additional aspace setup in the new process\n");
}
}
/* EOF */

View file

@ -1,470 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/powerpc/page.c
* PURPOSE: Low level memory managment manipulation
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Revised for PowerPC by arty
*/
/* INCLUDES ***************************************************************/
#include <ntoskrnl.h>
#include <ppcmmu/mmu.h>
//#define NDEBUG
#include <debug.h>
/* GLOBALS *****************************************************************/
#define HYPERSPACE_PAGEDIR_PTR ((PVOID)0xc0000000)
#define PA_PRESENT (1ll<<63)
#define PA_USER (1ll<<62)
#define PA_ACCESSED 0x200
#define PA_DIRTY 0x100
#define PA_WT 0x20
#define PA_CD 0x10
#define PA_READWRITE 3
#define HYPERSPACE (0xc0400000)
#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
#if defined(__GNUC__)
#define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
#else
__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
{
LARGE_INTEGER dummy;
dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
return dummy;
}
#endif
/* FUNCTIONS ***************************************************************/
VOID
NTAPI
MiFlushTlbIpiRoutine(PVOID Address)
{
if (Address == (PVOID)0xffffffff)
{
__asm__("tlbsync");
}
else if (Address == (PVOID)0xfffffffe)
{
__asm__("tlbsync");
}
else
{
__asm__("tlbi %0" : "=r" (Address));
}
}
VOID
MiFlushTlb(PULONG Pt, PVOID Address)
{
__asm__("tlbi %0" : "=r" (Address));
}
static ULONG
ProtectToFlags(ULONG flProtect)
{
return MMU_ALL_RW; // XXX hack
}
NTSTATUS
NTAPI
MmCopyMmInfo(PEPROCESS Src,
PEPROCESS Dest,
PPHYSICAL_ADDRESS DirectoryTableBase)
{
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
ASSERT(FALSE);
return(STATUS_SUCCESS);
}
BOOLEAN
NTAPI
MmCreateProcessAddressSpace(IN ULONG MinWs,
IN PEPROCESS Process,
IN PLARGE_INTEGER DirectoryTableBase)
{
ASSERT(FALSE);
return TRUE;
}
VOID
NTAPI
MmDeletePageTable(PEPROCESS Process, PVOID Address)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
Process, CurrentProcess);
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(&Process->Pcb);
}
if (Process)
{
DPRINT1("Revoking VSID %d\n", (paddr_t)Process->UniqueProcessId);
MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
}
else
{
DPRINT1("No vsid to revoke\n");
}
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
VOID
NTAPI
MmFreePageTable(PEPROCESS Process, PVOID Address)
{
MmDeletePageTable(Process, Address);
}
PVOID
NTAPI
MmGetPhysicalAddressProcess(PEPROCESS Process, PVOID Addr)
{
ppc_map_info_t info = { 0 };
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Addr;
MmuInqPage(&info, 1);
return (PVOID)info.phys;
}
PFN_NUMBER
NTAPI
MmGetPfnForProcess(PEPROCESS Process,
PVOID Address)
{
return((PFN_NUMBER)MmGetPhysicalAddressProcess(Process, Address) >> PAGE_SHIFT);
}
VOID
NTAPI
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
BOOLEAN* WasDirty, PPFN_NUMBER Page)
/*
* FUNCTION: Delete a virtual mapping
*/
{
ppc_map_info_t info = { 0 };
DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
Process, Address, WasDirty, Page);
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Address;
MmuInqPage(&info, 1);
/*
* Return some information to the caller
*/
if (WasDirty != NULL)
{
*WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
}
if (Page != NULL)
{
*Page = info.phys >> PAGE_SHIFT;
}
}
VOID
NTAPI
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
SWAPENTRY* SwapEntry)
/*
* FUNCTION: Delete a virtual mapping
*/
{
ppc_map_info_t info = { 0 };
/*
* Decrement the reference count for this page table.
*/
if (Process != NULL &&
((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
Address < MmSystemRangeStart)
{
PUSHORT Ptrc;
Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
MmFreePageTable(Process, Address);
}
/*
* Return some information to the caller
*/
MmuInqPage(&info, 1);
*SwapEntry = info.phys;
}
BOOLEAN
NTAPI
MmIsDirtyPage(PEPROCESS Process, PVOID Address)
{
ppc_map_info_t info = { 0 };
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Address;
MmuInqPage(&info, 1);
return !!(info.flags & MMU_PAGE_DIRTY);
}
VOID
NTAPI
MmSetCleanPage(PEPROCESS Process, PVOID Address)
{
}
VOID
NTAPI
MmSetDirtyPage(PEPROCESS Process, PVOID Address)
{
}
BOOLEAN
NTAPI
MmIsPagePresent(PEPROCESS Process, PVOID Address)
{
ppc_map_info_t info = { 0 };
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Address;
MmuInqPage(&info, 1);
return !!info.phys;
}
ULONGLONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{
return 0; // XXX arty
}
BOOLEAN
NTAPI
MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
{
ULONG Entry;
Entry = MmGetPageEntryForProcess(Process, Address);
return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
}
NTSTATUS
NTAPI
MmCreatePageFileMapping(PEPROCESS Process,
PVOID Address,
SWAPENTRY SwapEntry)
{
if (Process == NULL && Address < MmSystemRangeStart)
{
DPRINT1("No process\n");
ASSERT(FALSE);
}
if (Process != NULL && Address >= MmSystemRangeStart)
{
DPRINT1("Setting kernel address with process context\n");
ASSERT(FALSE);
}
if (SwapEntry & (1 << 31))
{
ASSERT(FALSE);
}
// XXX arty
return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
ULONG PageCount)
{
ULONG Attributes;
PVOID Addr;
ULONG i;
ppc_map_info_t info = { 0 };
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
if (Process == NULL)
{
if (Address < MmSystemRangeStart)
{
DPRINT1("No process\n");
ASSERT(FALSE);
}
if (PageCount > 0x10000 ||
(ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
{
DPRINT1("Page count to large\n");
ASSERT(FALSE);
}
}
else
{
if (Address >= MmSystemRangeStart)
{
DPRINT1("Setting kernel address with process context\n");
ASSERT(FALSE);
}
if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
(ULONG_PTR) Address / PAGE_SIZE + PageCount >
(ULONG_PTR)MmSystemRangeStart / PAGE_SIZE)
{
DPRINT1("Page Count to large\n");
ASSERT(FALSE);
}
}
Attributes = ProtectToFlags(flProtect);
Addr = Address;
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
{
Process = PsGetCurrentProcess();
info.proc = ((Addr < MmSystemRangeStart) && Process) ?
(int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Addr;
info.flags = Attributes;
MmuMapPage(&info, 1);
//(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
if (Address < MmSystemRangeStart &&
((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
Attributes & PA_PRESENT)
{
#if 0
PUSHORT Ptrc;
Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
#endif
}
}
return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
MmCreateVirtualMapping(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
ULONG PageCount)
{
ULONG i;
for (i = 0; i < PageCount; i++)
{
if (!MmIsUsablePage(Pages[i]))
{
DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i]));
ASSERT(FALSE);
}
}
return(MmCreateVirtualMappingUnsafe(Process,
Address,
flProtect,
Pages,
PageCount));
}
ULONG
NTAPI
MmGetPageProtect(PEPROCESS Process, PVOID Address)
{
ULONG Protect = 0;
ppc_map_info_t info = { 0 };
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Address;
MmuInqPage(&info, 1);
if (!info.phys) { return PAGE_NOACCESS; }
if (!(info.flags & MMU_KMASK))
{
Protect |= PAGE_SYSTEM;
if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
Protect = PAGE_READWRITE;
else if (info.flags & MMU_KR)
Protect = PAGE_EXECUTE_READ;
}
else
{
if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
Protect = PAGE_READWRITE;
else
Protect = PAGE_EXECUTE_READ;
}
return(Protect);
}
VOID
NTAPI
MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
{
//ULONG Attributes = 0;
DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
Process, Address, flProtect);
#if 0
Attributes = ProtectToPTE(flProtect);
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt == NULL)
{
ASSERT(FALSE);
}
InterlockedExchange((PLONG)Pt, PAGE_MASK(*Pt) | Attributes | (*Pt & (PA_ACCESSED|PA_DIRTY)));
MiFlushTlb(Pt, Address);
#endif
}
CODE_SEG("INIT")
VOID
NTAPI
MmInitGlobalKernelPageDirectory(VOID)
{
}
/* Create a simple, primitive mapping at the specified address on a new page */
NTSTATUS MmPPCCreatePrimitiveMapping(ULONG_PTR PageAddr)
{
NTSTATUS result;
ppc_map_info_t info = { 0 };
info.flags = MMU_KRW;
info.addr = (vaddr_t)PageAddr;
result = MmuMapPage(&info, 1) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
return result;
}
/* Use our primitive allocator */
PFN_NUMBER MmPPCPrimitiveAllocPage()
{
paddr_t Result = MmuGetPage();
DbgPrint("Got Page %x\n", Result);
return Result / PAGE_SIZE;
}
/* EOF */

View file

@ -1,111 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/powerpc/pfault.c
* PURPOSE: Paging file functions
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include <ppcmmu/mmu.h>
/* EXTERNS *******************************************************************/
NTSTATUS
NTAPI
MmNotPresentFault(KPROCESSOR_MODE Mode,
ULONG_PTR Address,
BOOLEAN FromMdl);
extern ULONG KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2);
/* FUNCTIONS *****************************************************************/
VOID MmpPpcTrapFrameToTrapFrame(ppc_trap_frame_t *frame, PKTRAP_FRAME Tf)
{
RtlCopyMemory(&Tf->Gpr0, frame->gpr, 12 * sizeof(ULONG));
Tf->Lr = frame->lr;
Tf->Cr = frame->cr;
Tf->Ctr = frame->ctr;
Tf->Xer = frame->xer;
Tf->Iar = frame->srr0;
Tf->Msr = frame->srr1 & 0xffff;
Tf->Dr0 = frame->dar;
Tf->Dr1 = frame->dsisr;
}
void CopyFrame(int *oldframe, int *ourframe)
{
int i;
for (i = 0; i < sizeof(ppc_trap_frame_t) / sizeof(int); i++)
{
ourframe[i] = GetPhys((int)&oldframe[i]);
}
}
void KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
{
NTSTATUS Status = STATUS_SUCCESS;
KPROCESSOR_MODE Mode;
EXCEPTION_RECORD Er;
KTRAP_FRAME Tf;
BOOLEAN AccessFault = !!(frame->dsisr & (1<<28));
vaddr_t VirtualAddr;
PVOID TrapInfo = NULL;
/* get the faulting address */
if (trap == 4) /* Instruction miss */
VirtualAddr = frame->srr0;
else /* Data miss */
VirtualAddr = frame->dar;
/* MSR_PR */
Mode = frame->srr1 & 0x4000 ? UserMode : KernelMode;
DPRINT("Page Fault at %08x\n", frame->srr0);
/* handle the fault */
if (AccessFault)
{
Status = MmAccessFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
}
else
{
Status = MmNotPresentFault(Mode, VirtualAddr, FALSE);
}
if (NT_SUCCESS(Status))
{
MmuCallbackRet();
}
if (KeGetCurrentThread()->ApcState.UserApcPending)
{
KIRQL oldIrql;
KeRaiseIrql(APC_LEVEL, &oldIrql);
KiDeliverApc(UserMode, NULL, NULL);
KeLowerIrql(oldIrql);
}
MmpPpcTrapFrameToTrapFrame(frame, &Tf);
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
Er.ExceptionFlags = 0;
Er.ExceptionRecord = NULL;
Er.ExceptionAddress = (PVOID)frame->srr0;
Er.NumberParameters = 2;
Er.ExceptionInformation[0] = AccessFault;
Er.ExceptionInformation[1] = VirtualAddr;
/* FIXME: Which exceptions are noncontinuable? */
Er.ExceptionFlags = 0;
KiDispatchException(&Er, 0, &Tf, Mode, TRUE);
MmuCallbackRet();
}

View file

@ -370,22 +370,6 @@ elseif(ARCH STREQUAL "arm")
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/ARM3/arm/init.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/arm/psctx.c
${REACTOS_SOURCE_DIR}/ntoskrnl/rtl/arm/rtlexcpt.c)
elseif(ARCH STREQUAL "powerpc")
list(APPEND ASM_SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/main_asm.S
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/ctxhelp.S)
list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/config/powerpc/cmhardwr.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/cpu.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/exp.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/kiinit.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/ppc_irq.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/stubs.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/systimer.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/thrdini.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/powerpc/ctxswitch.c
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/powerpc/pfault.c
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/powerpc/page.c)
endif()
if(NOT _WINKD_)

View file

@ -1,277 +0,0 @@
#ifndef PPCMMU_H
#define PPCMMU_H
#include <string.h>
/* PPC MMU object --
* Always called from kernel mode, maps the first 16 megabytes and uses 16
* bytes per page between 0x30000 and 16 megs. Maximum memory size is 3 gig.
*
* Physical Memory Map:
* 0x00300 -- Data Miss
* 0x00400 -- Code Miss
* 0x10000 -- MMU ucode
* 0x20000 -- PTEG
* 0x30000 -- Full map
*
* Actions:
*
* 1** -- MMU Related
*
* 100 -- Initialize
* -- No arguments
* 101 -- Map page
* r4 -- virtual address
* r5 -- ppc_map_info_t
* 102 -- Erase page
* r4 -- virtual address
* 103 -- Set segment VSID
* r4 -- Start seg
* r5 -- End seg
* r6 -- Vsid
* 104 -- Set trap callback
* r4 -- Trap number
* r5 -- Callback address (VA)
* 105 -- Query page
* r4 -- Page addr
* r5 -- Address of info struct
* 106 -- Unit Test
* 107 -- Turn on paging
* 108 -- Unmap process
* 109 -- Get lowest unallocated page
* 10a -- Alloc vsid
* 10b -- Revoke vsid
* 10c -- Allocate a page and return it
* 10d -- Return from trap callback
* 10e -- Dump Map
*
* 2** -- Debug Stub and Interrupt Vectoring
*
* 200 -- GDB Initialize
* r4 -- Device type
* r4 -- Serial port addr
* 201 -- GDB Enter
* r4 -- Signal number
*/
#define MMUCODE 0x10000
#define HTABORG 0x20000
#define HTABSIZ 0x10000
#define PAGETAB 0x30000
#define PpcHashedPTE ((ppc_pteg_t*)(HTABORG))
#define PpcPageTable ((ppc_map_t*)(PAGETAB))
#define PPC_PAGE_ADDR(x) ((x) << 12)
#define PPC_PAGE_NUMBER(x) ((x) >> 12)
#define PPC_VSID_MASK 0xffffff
#define PPC_PAGE_MASK 0xfff
#define MMU_NONE 0
#define MMU_KR 8
#define MMU_KW 4
#define MMU_UR 2
#define MMU_UW 1
#define MMU_ALL_R 10
#define MMU_KRW 12
#define MMU_KRW_UR 14
#define MMU_ALL_RW 15
#define MMU_PAGE_ACCESS 0x40000000
#define MMU_PAGE_DIRTY 0x80000000
#define MMU_KMASK 12
#define MMU_UMASK 3
extern char _binary_mmucode_start[], _binary_mmucode_end[];
/* thanks geist */
typedef unsigned long paddr_t;
typedef unsigned long vaddr_t;
typedef struct _ppc_pte_t {
unsigned long pteh, ptel;
} ppc_pte_t;
typedef struct _ppc_pteg_t {
ppc_pte_t block[8];
} ppc_pteg_t;
typedef struct _ppc_map_t {
ppc_pte_t pte;
unsigned long proc;
vaddr_t addr;
} ppc_map_t;
typedef struct _ppc_map_info_t {
unsigned long flags, proc;
vaddr_t addr;
paddr_t phys;
} ppc_map_info_t;
typedef struct _ppc_trap_frame_t {
unsigned long gpr[32];
unsigned long long fpr[32];
unsigned long srr0, srr1, cr, lr, ctr, dsisr, dar, xer;
} ppc_trap_frame_t;
typedef int (*MmuTrapHandler)(int trapid, ppc_trap_frame_t *trap);
#include "mmuutil.h"
static inline int PPCMMU(int action, void *arg1, void *arg2, void *arg3)
{
/* Set Bat0 to mmu object address */
int i, batu, batl, usebat[2] = { 0, 1 }, gotbat = 0, pc, mask;
volatile int ret;
int (*mmumain)(int action, void *arg1, void *arg2, void *arg3) = (void *)MMUCODE;
__asm__("bl 1f\n\t"
"\n1:\n\t"
"mflr %0\n\t" : "=r" (pc));
for(i = 0, gotbat = 0; i < 4; i++)
{
/* Use the space above the trap handlers to store the old bats */
GetBat(i, 0, &batu, &batl);
SetPhys(0xf000 + i * 16, batu);
SetPhys(0xf004 + i * 16, batl);
GetBat(i, 1, &batu, &batl);
SetPhys(0xf008 + i * 16, batu);
SetPhys(0xf00c + i * 16, batl);
if (gotbat < 2)
{
if(batu & 0xffc)
{
mask = ~(0x1ffff | ((batu & 0xffc)>>2)<<17);
if(!(batu & 2) || ((batu & mask) != (pc & mask)))
usebat[gotbat++] = i;
} else {
mask = ~(0x1ffff | (batl << 17));
if(!(batl & 0x40) || ((batu & mask) != (pc & mask)))
usebat[gotbat++] = i;
}
}
}
batu = 0xff;
batl = 0x7f;
SetBat(usebat[0], 0, batu, batl);
SetBat(usebat[0], 1, batu, batl);
batu += 8192 * 1024;
batl += 8192 * 1024;
SetBat(usebat[1], 0, batu, batl);
SetBat(usebat[1], 1, batu, batl);
ret = mmumain(action, arg1, arg2, arg3);
return ret;
}
/* Expand this only if used ... That makes dependence on libmmu_code.a depend
* on whether MmuInit is called in a clean way.
*/
#define MmuInit() _MmuInit(&_binary_mmucode_start, &_binary_mmucode_end)
/* Copy in the mmu code and call init
* This bootstrap should only be called the first time (i.e. in the bootloader
* or the early boot code). Part of the purpose of this library is to
* eliminate the need to do a complex mmu handoff between boot stages.
*/
static inline void _MmuInit(void *_start, void *_end)
{
int target = MMUCODE, copy;
int *start = (int *)_start;
while(start < (int *)_end)
{
memcpy(&copy, start++, sizeof(int));
SetPhys(target, copy);
target += sizeof(int);
}
PPCMMU(0x100, 0, 0, 0);
}
static inline int MmuMapPage(ppc_map_info_t *info, int count)
{
return PPCMMU(0x101, info, (void *)count, 0);
}
static inline void MmuUnmapPage(ppc_map_info_t *info, int count)
{
PPCMMU(0x102, info, (void *)count, 0);
}
static inline void MmuSetVsid(int start, int end, int vsid)
{
PPCMMU(0x103, (void *)start, (void *)end, (void *)vsid);
}
static inline MmuTrapHandler MmuSetTrapHandler(int trap, MmuTrapHandler cb)
{
return (MmuTrapHandler)PPCMMU(0x104, (void *)trap, (void *)cb, 0);
}
static inline void MmuInqPage(ppc_map_info_t *info, int count)
{
PPCMMU(0x105, info, (void *)count, 0);
}
static inline int MmuUnitTest()
{
return PPCMMU(0x106, 0, 0, 0);
}
static inline int MmuTurnOn(void *fun, void *arg)
{
return PPCMMU(0x107, fun, arg, 0);
}
static inline void MmuSetMemorySize(paddr_t size)
{
PPCMMU(0x108, (void *)size, 0, 0);
}
static inline paddr_t MmuGetFirstPage()
{
return (paddr_t)PPCMMU(0x109, 0, 0, 0);
}
static inline void *MmuAllocVsid(int vsid, int mask)
{
return (void *)PPCMMU(0x10a, (void *)vsid, (void *)mask, 0);
}
static inline void MmuRevokeVsid(int vsid, int mask)
{
PPCMMU(0x10b, (void *)vsid, (void *)mask, 0);
}
static inline paddr_t MmuGetPage()
{
return PPCMMU(0x10c, 0,0,0);
}
static inline void MmuCallbackRet()
{
PPCMMU(0x10d, 0,0,0);
}
static inline void MmuDumpMap()
{
PPCMMU(0x10e, 0,0,0);
}
static inline void MmuDbgInit(int deviceType, int devicePort)
{
PPCMMU(0x200, (void *)deviceType, (void *)devicePort, 0);
}
static inline void MmuDbgEnter(int signal)
{
PPCMMU(0x201, (void *)signal, 0, 0);
}
#endif/*PPCMMU_H*/

View file

@ -1,23 +0,0 @@
#ifndef FREELDR_MMU_H
#define FREELDR_MMU_H
int GetDEC(void);
int GetMSR(void);
int GetPhys( paddr_t addr );
int GetPhysHalf( paddr_t addr );
int GetPhysByte( paddr_t addr );
void SetPhys( paddr_t addr, int val );
void SetPhysHalf( paddr_t addr, int val );
void SetPhysByte( paddr_t addr, int val );
int GetSR(int n);
void SetSR(int n, int val);
void GetBat( int bat, int inst, int *batHi, int *batLo );
void SetBat( int bat, int inst, int batHi, int batLo );
int GetSDR1(void);
void SetSDR1( int newsdr );
int BatHit( int bath, int batl, int virt );
int BatTranslate( int bath, int batl, int virt );
/* translate address */
int PpcVirt2phys( vaddr_t virt, int inst );
int PtegNumber( vaddr_t virt, int hfun );
#endif/*FREELDR_MMU_H*/

View file

@ -34,7 +34,6 @@ endif()
add_subdirectory(ioevent)
add_subdirectory(lsalib)
add_subdirectory(nt)
add_subdirectory(ppcmmu)
add_subdirectory(pseh)
if(KDBG)

View file

@ -64,8 +64,6 @@ elseif(ARCH STREQUAL "amd64")
list(APPEND CHKSTK_ASM_SOURCE except/amd64/chkstk_ms.s)
elseif(ARCH STREQUAL "arm")
list(APPEND CHKSTK_ASM_SOURCE except/arm/chkstk_asm.s)
elseif(ARCH STREQUAL "powerpc")
list(APPEND CHKSTK_ASM_SOURCE except/powerpc/chkstk_asm.s)
endif()
add_asm_files(chkstk_lib_asm ${CHKSTK_ASM_SOURCE})

View file

@ -1,22 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Stack checker
* FILE: lib/sdk/crt/except/powerpc/chkstk_asm.s
* PROGRAMER: arty
*/
.globl _chkstk
.globl _alloca_probe
/*
_chkstk() is called by all stack allocations of more than 4 KB. It grows the
stack in areas of 4 KB each, trying to access each area. This ensures that the
guard page for the stack is hit, and the stack growing triggered
*/
_chkstk:
_alloca_probe:
/* return */
blr
/* EOF */

View file

@ -1,75 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/sdk/crt/except/powerpc/seh.s
* PURPOSE: SEH Support for the CRT
* PROGRAMMERS: arty
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
#define DISPOSITION_COLLIDED_UNWIND 3
/* GLOBALS *******************************************************************/
.globl _global_unwind2
.globl _local_unwind2
.globl _abnormal_termination
.globl _except_handler2
.globl _except_handler3
/* FUNCTIONS *****************************************************************/
unwind_handler:
blr
_global_unwind2:
blr
_local_unwind2:
blr
_except_handler2:
blr
_except_handler3:
blr
//
//
// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME
// sorry
//
//
.globl RtlpGetStackLimits
RtlpGetStackLimits:
stwu 1,16(1)
mflr 0
stw 0,4(1)
stw 3,8(1)
stw 4,12(1)
/* Get the current thread */
lwz 3,KPCR_CURRENT_THREAD(13)
/* Get the stack limits */
lwz 4,KTHREAD_STACK_LIMIT(3)
lwz 5,KTHREAD_INITIAL_STACK(3)
subi 5,5,SIZEOF_FX_SAVE_AREA
/* Return them */
lwz 3,8(1)
stw 4,0(3)
lwz 3,12(1)
stw 5,0(3)
addi 1,1,16
/* return */
blr

View file

@ -1,8 +0,0 @@
list(APPEND SOURCE dummy.c)
if(ARCH STREQUAL "powerpc")
list(APPEND SOURCE mmuutil.c)
endif()
add_library(ppcmmu ${SOURCE})

View file

@ -1,222 +0,0 @@
/* PowerPC Trap Handler first Half */
.text
.globl mmumain
.globl _mmumain
mmumain:
mr 0,1
lis 1,2
subi 1,1,448
stw 0,20(1)
stw 2,24(1)
stw 3,28(1)
stw 4,32(1)
stw 5,36(1)
stw 6,40(1)
stw 7,44(1)
stw 8,48(1)
stw 9,52(1)
stw 10,56(1)
stw 11,60(1)
stw 12,64(1)
stw 13,68(1)
stw 14,72(1)
stw 15,76(1)
stw 16,80(1)
stw 17,84(1)
stw 18,88(1)
stw 19,92(1)
stw 20,96(1)
stw 21,100(1)
stw 22,104(1)
stw 23,108(1)
stw 24,112(1)
stw 25,116(1)
stw 26,120(1)
stw 27,124(1)
stw 28,128(1)
stw 29,132(1)
stw 30,136(1)
stw 31,140(1)
mfsrr0 0
stw 0,400(1)
mfmsr 0
stw 0,404(1)
mfcr 0
stw 0,408(1)
mflr 0
stw 0,412(1)
mfctr 0
stw 0,416(1)
mfdsisr 0
stw 0,420(1)
mfdar 0
stw 0,424(1)
mfxer 0
stw 0,428(1)
addi 7,1,16
lis 8,_mmumain@ha
addi 8,8,_mmumain@l
mtctr 8
bctrl
addi 1,1,16
lwz 2,8(1)
/* Don't reload r3, since we'll return a result */
lwz 4,16(1)
lwz 5,20(1)
lwz 6,24(1)
lwz 7,28(1)
lwz 8,32(1)
lwz 9,36(1)
lwz 10,40(1)
lwz 11,44(1)
lwz 12,48(1)
lwz 13,52(1)
lwz 14,56(1)
lwz 15,60(1)
lwz 16,64(1)
lwz 17,68(1)
lwz 18,72(1)
lwz 19,76(1)
lwz 20,80(1)
lwz 21,84(1)
lwz 22,88(1)
lwz 23,92(1)
lwz 24,96(1)
lwz 25,100(1)
lwz 26,104(1)
lwz 27,108(1)
lwz 28,112(1)
lwz 29,116(1)
lwz 30,120(1)
lwz 31,124(1)
lwz 0,392(1)
mtcr 0
lwz 0,396(1)
mtsrr0 0
lwz 0,400(1)
mtctr 0
lwz 0,388(1) /* Copy out new MSR bits if needed */
lwz 1,4(1)
mtsrr1 0
rfi
.globl trap_start
.globl trap_end
trap_start:
mtsprg1 1
lis 1,2
subi 1,1,448
stw 0,16(1)
mfsprg1 0
stw 0,20(1)
stw 2,24(1)
stw 3,28(1)
stw 4,32(1)
stw 5,36(1)
stw 6,40(1)
stw 7,44(1)
stw 8,48(1)
stw 9,52(1)
stw 10,56(1)
stw 11,60(1)
stw 12,64(1)
stw 13,68(1)
stw 14,72(1)
stw 15,76(1)
stw 16,80(1)
stw 17,84(1)
stw 18,88(1)
stw 19,92(1)
stw 20,96(1)
stw 21,100(1)
stw 22,104(1)
stw 23,108(1)
stw 24,112(1)
stw 25,116(1)
stw 26,120(1)
stw 27,124(1)
stw 28,128(1)
stw 29,132(1)
stw 30,136(1)
stw 31,140(1)
mfsrr0 0
stw 0,400(1)
mfsrr1 0
stw 0,404(1)
mfcr 0
stw 0,408(1)
mflr 0
stw 0,412(1)
mfctr 0
stw 0,416(1)
mfdsisr 0
stw 0,420(1)
mfdar 0
stw 0,424(1)
mfxer 0
stw 0,428(1)
bl 1f
1: mflr 5
addi 4,1,16
rlwinm 3,5,24,0xff
lwz 5,36(5)
mtctr 5
lis 5,trap_finish_start@ha
addi 5,5,trap_finish_start@l
mtlr 5
bctr
trap_end:
.space 4
.globl trap_finish_start
trap_finish_start:
addi 1,1,16
lwz 2,8(1)
lwz 3,12(1)
lwz 4,16(1)
lwz 5,20(1)
lwz 6,24(1)
lwz 7,28(1)
lwz 8,32(1)
lwz 9,36(1)
lwz 10,40(1)
lwz 11,44(1)
lwz 12,48(1)
lwz 13,52(1)
lwz 14,56(1)
lwz 15,60(1)
lwz 16,64(1)
lwz 17,68(1)
lwz 18,72(1)
lwz 19,76(1)
lwz 20,80(1)
lwz 21,84(1)
lwz 22,88(1)
lwz 23,92(1)
lwz 24,96(1)
lwz 25,100(1)
lwz 26,104(1)
lwz 27,108(1)
lwz 28,112(1)
lwz 29,116(1)
lwz 30,120(1)
lwz 31,124(1)
lwz 0,384(1)
mtsrr0 0
lwz 0,388(1)
mtsrr1 0
lwz 0,392(1)
mtcr 0
lwz 0,396(1)
mtlr 0
lwz 0,400(1)
mtctr 0
lwz 0,404(1)
mtdsisr 0
lwz 0,412(1)
mtdar 0
lwz 0,416(1)
mtxer 0
lwz 0,0(1)
lwz 1,4(1)
rfi

View file

View file

@ -1,475 +0,0 @@
/****************************************************************************
THIS SOFTWARE IS NOT COPYRIGHTED
HP offers the following for use in the public domain. HP makes no
warranty with regard to the software or it's performance and the
user accepts the software "AS IS" with all faults.
HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
****************************************************************************/
/****************************************************************************
* Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
*
* Module name: remcom.c $
* Revision: 1.34 $
* Date: 91/03/09 12:29:49 $
* Contributor: Lake Stevens Instrument Division$
*
* Description: low level support for gdb debugger. $
*
* Considerations: only works on target hardware $
*
* Written by: Glenn Engel $
* ModuleState: Experimental $
*
* NOTES: See Below $
*
* Modified for 386 by Jim Kingdon, Cygnus Support.
* Modified for ReactOS by Casper S. Hornstrup <chorns@users.sourceforge.net>
* Modified heavily for PowerPC ReactOS by arty
*
* To enable debugger support, two things need to happen. One, setting
* up a routine so that it is in the exception path, is necessary in order
* to allow any breakpoints or error conditions to be properly intercepted
* and reported to gdb.
* Two, a breakpoint needs to be generated to begin communication.
ER*
* Because gdb will sometimes write to the stack area to execute function
* calls, this program cannot rely on using the supervisor stack so it
* uses it's own stack area.
*
*************
*
* The following gdb commands are supported:
*
* command function Return value
*
* g return the value of the CPU Registers hex data or ENN
* G set the value of the CPU Registers OK or ENN
*
* mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
* MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
*
* c Resume at current address SNN ( signal NN)
* cAA..AA Continue at address AA..AA SNN
*
* s Step one instruction SNN
* sAA..AA Step one instruction from AA..AA SNN
*
* k kill
*
* ? What was the last sigval ? SNN (signal NN)
*
* All commands and responses are sent with a packet which includes a
* Checksum. A packet consists of
*
* $<packet info>#<Checksum>.
*
* where
* <packet info> :: <characters representing the command or response>
* <Checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
*
* When a packet is received, it is first acknowledged with either '+' or '-'.
* '+' indicates a successful transfer. '-' indicates a failed transfer.
*
* Example:
*
* Host: Reply:
* $m0,10#2a +$00010203040506070809101112131415#42
*
****************************************************************************/
#include "ppcmmu/mmu.h"
#define GDB_SAVE_SIZE 0x66
typedef struct _BREAKPOINT {
int OldCode;
int *Address;
} BREAKPOINT, *PBREAKPOINT;
BREAKPOINT BreakPoints[64];
char DataOutBuffer[1024];
volatile int DataOutAddr, DataOutCsum;
char DataInBuffer[128];
volatile int DataInAddr, ParseState = 0, ComputedCsum, ActualCsum;
volatile int PacketSent = 0, SendSignal = 0;
volatile int Continue = 0, Signal = 0;
volatile ppc_trap_frame_t RegisterSaves, *RegisterSaveArea = &RegisterSaves;
char *hex = "0123456789abcdef";
#define RCV 0
#define THR 0
#define BAUDLOW 0
#define BAUDHIGH 1
#define IER 1
#define FCR 2
#define ISR 2
#define LCR 3
#define MCR 4
#define LSR 5
#define MSR 6
#define SPR 7
extern void send(char *serport, char c);
extern char recv(char *serport);
extern void setup(char *serport, int baud);
char *serport = (char *)0x800003f8;
int isxdigit(int ch)
{
return
(ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f') ||
(ch >= '0' && ch <= '9');
}
inline void sync() {
__asm__("eieio\n\t"
"sync");
}
inline void send(char *serport, char c) {
/* Wait for Clear to Send */
while( !(GetPhysByte((paddr_t)serport+LSR) & 0x20) ) sync();
SetPhysByte((paddr_t)serport+THR, c);
sync();
}
inline int rdy(char *serport)
{
sync();
return (GetPhysByte((paddr_t)serport+LSR) & 0x20);
}
inline int chr(char *serport)
{
sync();
return GetPhysByte((paddr_t)serport+LSR) & 1;
}
inline char recv(char *serport) {
char c;
while( !chr(serport) ) sync();
c = GetPhysByte((paddr_t)serport+RCV);
sync();
return c;
}
void setup(char *serport, int baud) {
int x = 115200 / baud;
SetPhysByte((paddr_t)serport+LCR, 128);
sync();
SetPhysByte((paddr_t)serport+BAUDLOW, x & 255);
sync();
SetPhysByte((paddr_t)serport+BAUDHIGH, x >> 8);
sync();
SetPhysByte((paddr_t)serport+LCR, 3);
sync();
}
void SerialSetUp(int deviceType, void *deviceAddr, int baud)
{
int i;
serport = deviceAddr;
setup(serport, baud);
}
extern int SerialInterrupt(int signal, ppc_trap_frame_t *tf);
void IntEnable()
{
SetPhysByte((paddr_t)serport+IER, GetPhysByte((paddr_t)serport+IER) | 1);
}
void SerialWrite(int ch)
{
send(serport, ch);
}
int SerialRead()
{
return recv(serport);
}
int hex2int(int ch)
{
if (ch >= 'a' && ch <= 'f') return ch + 10 - 'a';
else if (ch >= 'A' && ch <= 'F') return ch + 10 - 'A';
else return ch - '0';
}
int PacketReadHexNumber(int dig)
{
int i;
int result = 0;
for (i = 0; i < dig && isxdigit(DataInBuffer[DataInAddr]); i++)
{
result <<= 4;
result |= hex2int(DataInBuffer[DataInAddr++]);
}
return result;
}
void PacketWriteChar(int ch)
{
DataOutCsum += ch;
DataOutBuffer[DataOutAddr++] = ch;
}
int PacketWriteHexNumber(int hnum, int dig)
{
int i;
hnum <<= (8 - dig) * 4;
for (i = 0; i < dig; i++)
{
PacketWriteChar(hex[(hnum >> 28) & 15]);
hnum <<= 4;
}
return i;
}
void PacketStart()
{
DataOutCsum = 0;
DataOutAddr = 0;
}
void PacketFinish()
{
int i, ch, count = 0;
PacketSent = 0;
SerialWrite('$');
for (i = 0; i < DataOutAddr; i++)
{
SerialWrite(DataOutBuffer[i]);
}
SerialWrite('#');
SerialWrite(hex[(DataOutCsum >> 4) & 15]);
SerialWrite(hex[DataOutCsum & 15]);
while(!chr(serport) && ((ch = SerialRead()) != '+') && (ch != '$'));
if (ch == '$')
{
ParseState = 0;
DataInAddr = 0;
ComputedCsum = 0;
}
}
void PacketWriteString(char *str)
{
while(*str) PacketWriteChar(*str++);
}
void PacketOk()
{
PacketStart();
PacketWriteString("OK");
PacketFinish();
}
void PacketEmpty()
{
PacketStart();
PacketFinish();
}
void PacketWriteSignal(int code)
{
PacketStart();
PacketWriteChar('S');
PacketWriteHexNumber(code, 2);
PacketFinish();
}
void PacketWriteError(int code)
{
PacketStart();
PacketWriteChar('E');
PacketWriteHexNumber(code, 2);
PacketFinish();
}
void marker() { }
void GotPacket()
{
int i, memaddr, memsize;
Continue = 0;
switch (DataInBuffer[DataInAddr++])
{
case 'g':
PacketStart();
for (i = 0; i < GDB_SAVE_SIZE; i++)
{
PacketWriteHexNumber(((int *)RegisterSaveArea)[i], 8);
}
PacketFinish();
break;
case 'G':
for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++)
{
((int *)RegisterSaveArea)[i] = PacketReadHexNumber(8);
}
PacketOk();
break;
case 'm':
memaddr = PacketReadHexNumber(8);
DataInAddr++;
memsize = PacketReadHexNumber(8);
PacketStart();
while(memsize-- > 0)
{
PacketWriteHexNumber(*((char *)memaddr++), 2);
}
PacketFinish();
break;
case 'M':
memaddr = PacketReadHexNumber(8);
DataInAddr++;
memsize = PacketReadHexNumber(8);
DataInAddr++;
while(memsize-- > 0)
{
*((char *)memaddr++) = PacketReadHexNumber(2);
}
PacketOk();
break;
case '?':
PacketWriteSignal(Signal);
break;
case 'c':
PacketOk();
Continue = 1;
break;
case 'S':
PacketOk();
Continue = 0;
break;
case 's':
RegisterSaveArea->srr1 |= 0x400;
PacketOk();
Continue = 1;
marker();
break;
case 'q':
switch (DataInBuffer[1])
{
case 'S': /*upported => nothing*/
PacketEmpty();
break;
case 'O': /*ffsets*/
PacketEmpty();
break;
}
break;
default:
PacketEmpty();
break;
}
}
int SerialInterrupt(int signal, ppc_trap_frame_t *tf)
{
int ch;
if (!chr(serport)) return 0;
Signal = signal;
RegisterSaveArea = tf;
do
{
ch = SerialRead();
if (ch == 3) /* Break in - tehe */
{
Continue = 0;
PacketWriteSignal(3);
}
else if (ch == '+')
{
/* Nothing */
}
else if (ch == '$')
{
DataInAddr = 0;
ParseState = 0;
ComputedCsum = 0;
ActualCsum = 0;
}
else if (ch == '#' && ParseState == 0)
{
ParseState = 2;
}
else if (ParseState == 0)
{
ComputedCsum += ch;
DataInBuffer[DataInAddr++] = ch;
}
else if (ParseState == 2)
{
ActualCsum = ch;
ParseState++;
}
else if (ParseState == 3)
{
ActualCsum = hex2int(ch) | (hex2int(ActualCsum) << 4);
ComputedCsum &= 255;
ParseState = -1;
if (ComputedCsum == ActualCsum)
{
ComputedCsum = 0;
DataInBuffer[DataInAddr] = 0;
DataInAddr = 0;
Continue = 0;
SerialWrite('+');
GotPacket();
}
else
SerialWrite('-');
}
else if (ParseState == -1)
SerialWrite('-');
}
while (!Continue);
return 1;
}
int TakeException(int n, ppc_trap_frame_t *tf)
{
Signal = n;
RegisterSaveArea = tf;
PacketWriteSignal(Signal);
SendSignal = 0;
Continue = 0;
while(!Continue) SerialInterrupt(n, tf);
return 1;
}
/* EOF */

View file

@ -1,8 +0,0 @@
OUTPUT_FORMAT(elf32-powerpc);
SECTIONS
{
.text : { *(.text) }
.data : { *(.data) *(.rodata) }
.bss : { *(.sbss) *(.bss) *(COMMON) }
}

View file

@ -1,766 +0,0 @@
#include <stdarg.h>
#include "ppcmmu/mmu.h"
#include "ppcmmu/mmuutil.h"
#include "mmuobject.h"
typedef unsigned long ULONG;
/*
The MMU Object:
0x00300 -- Data miss
0x00400 -- Instruction miss
0x10000 -- Entry point
... Code
0x20000 -- Physical map (PTE + Process Ptr + Address : 16 bytes)
4096 / 16 bytes = 256 entries per page
256 pages = 1Megabyte = 1 page table page
Setup by freeldr and used to build the kernel map, then used by the kernel
Calling:
r3 -- Action
r4 .. r6 -- Args
Actions:
00 Init
01 Map pages
02 erase pages
03 set segment vsid
04 page miss callback
05 inquire page
06 unit test
07 alloc page
08 set memory size
09 get first usable page
10 alloc vsid
11 revoke vsid
*/
#define MMU_ADDR_RESERVED ((vaddr_t)-2)
MmuTrapHandler callback[0x30];
typedef struct _MmuFreePage {
int page;
struct _MmuFreePage *next;
} MmuFreePage;
typedef struct _MmuFreeTree {
struct _MmuFreeTree *next;
} MmuFreeTree;
typedef struct _MmuVsidTree {
ppc_map_t *leaves[256];
} MmuVsidTree;
typedef struct _MmuVsidInfo {
int vsid;
struct _MmuVsidInfo *next;
MmuVsidTree *tree[256];
} MmuVsidInfo;
MmuFreePage *FreeList = 0;
// Pages are allocated one by one until NextPage == RamSize >> PPC_PAGE_SHIFT
// Then we take only from the free list
int Clock = 0, TreeAlloc = 0, GdbAttach = 0, Booted = 0, Vsid[16];
paddr_t RamSize, FirstUsablePage, NextPage;
MmuVsidTree *NextTreePage = 0;
MmuFreeTree *FreeTree;
MmuVsidInfo *Segs[16], *VsidHead = 0;
extern void fmtout(const char *fmt, ...);
extern char *serport;
int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr);
void SerialSetUp(int deviceType, void *deviceAddr, int baud);
int SerialInterrupt(int n, ppc_trap_frame_t *tf);
void TakeException(int n, ppc_trap_frame_t *tf);
int mmuisfreepage(paddr_t pageno);
void copy(void *t, void *s, int b);
paddr_t mmunewpage();
void dumpmap();
void trapcallback(int action, ppc_trap_frame_t *trap_frame);
int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
{
ppc_trap_frame_t *trap_frame = (action >= 0x100) ? tf : arg1;
int ret = 0, tmp, i;
switch(action)
{
/* Trap Handlers */
case 3:
if(!ptegreload(trap_frame, trap_frame->dar))
{
trapcallback(action, trap_frame);
}
break;
case 4:
if(!ptegreload(trap_frame, trap_frame->srr0))
{
trapcallback(action, trap_frame);
}
break;
case 5:
/* EE -- Try to get a serial interrupt if debugging enabled, then fall
* back to primary handler
*/
if (!SerialInterrupt(action, trap_frame) && callback[action])
{
trapcallback(action, trap_frame);
}
break;
case 0:
case 2:
case 6:
case 7:
case 8:
case 9:
case 0xa:
case 0xc:
case 0x20:
trapcallback(action, trap_frame);
break;
/* MMU Functions */
case 0x100:
initme();
trap_frame->srr1 |= 0x8000;
break;
case 0x101:
ret = mmuaddpage(arg1, (int)arg2);
break;
case 0x102:
mmudelpage(arg1, (int)arg2);
break;
case 0x103:
mmusetvsid((int)arg1, (int)arg2, (int)arg3);
break;
case 0x104:
ret = (int)callback[(int)arg1];
callback[(int)arg1] = (MmuTrapHandler)arg2;
break;
case 0x105:
mmugetpage(arg1, (int)arg2);
break;
case 0x106:
ret = mmunitest();
break;
case 0x107:
callkernel(arg1, arg2);
break;
case 0x108:
mmusetramsize((paddr_t)arg1);
break;
case 0x109:
return FirstUsablePage;
case 0x10a:
mmuallocvsid((int)arg1, (int)arg2);
break;
case 0x10b:
mmufreevsid((int)arg1, (int)arg2);
break;
case 0x10c:
ret = mmunewpage();
break;
case 0x10d:
copy(trap_frame, (void *)0xf040, sizeof(*trap_frame));
__asm__("mr 1,%0\n\tb trap_finish_start" : : "r"
(((int)trap_frame) - 16));
break;
case 0x10e:
dumpmap();
break;
case 0x200:
SerialSetUp((int)arg1, arg2, 9600);
break;
case 0x201:
TakeException((int)arg1, trap_frame);
break;
default:
while(1);
}
/* Restore bats when we were called voluntarily. We may not get a chance
* to do this after returning.
*
* At this point, we're in address space that matches physical space.
* We turn off mapping, restore bats, then let rfi switch us back to where
* we came.
*/
if (action >= 0x100)
{
__asm__("mfmsr %0" : "=r" (tmp));
tmp &= ~0x30;
__asm__("mtmsr %0" : : "r" (tmp));
for(i = 0; i < 4; i++) {
SetBat(i, 0, GetPhys(0xf000 + i * 16), GetPhys(0xf004 + i * 16));
SetBat(i, 1, GetPhys(0xf008 + i * 16), GetPhys(0xf00c + i * 16));
}
}
return ret;
}
void trapcallback(int action, ppc_trap_frame_t *trap_frame)
{
if ((paddr_t)callback[action] < PAGETAB)
callback[action](action, trap_frame);
else
{
int framecopy = 0xf040;
copy((void *)framecopy, trap_frame, sizeof(*trap_frame));
trap_frame->srr0 = (int)callback[action];
trap_frame->srr1 &= 0x7fff;
trap_frame->gpr[3] = action;
trap_frame->gpr[4] = framecopy;
__asm__("mr 1,%0\n\tsubi 1,1,16\n\tb trap_finish_start" : : "r" (trap_frame));
}
}
void outchar(char c)
{
SetPhysByte(0x800003f8, c);
}
void copy(void *target, void *src, int bytes)
{
while(bytes--) *((char *)target++) = *((char *)src++);
}
void outstr(const char *str)
{
while(*str) outchar(*str);
}
void outdig(int dig)
{
if(dig < 10) outchar(dig + '0');
else outchar(dig - 10 + 'A');
}
void outnum(unsigned long num)
{
int i;
for( i = 0; i < 8; i++ )
{
outdig(num >> 28);
num <<= 4;
}
}
void fmtout(const char *str, ...)
{
va_list ap;
va_start(ap, str);
while(*str)
{
if(*str == '%')
{
if(str[1] == '%')
{
outchar('%');
}
else if(str[1] == 's')
{
outstr(va_arg(ap, const char *));
}
else
{
outnum(va_arg(ap, int));
}
str++;
}
else
{
outchar(*str);
}
str++;
}
va_end(ap);
}
void mmusetramsize(paddr_t ramsize)
{
ppc_map_t *last_map = &PpcPageTable[PPC_PAGE_NUMBER(ramsize)];
if(!RamSize)
{
RamSize = ramsize;
FirstUsablePage = (paddr_t)last_map;
NextPage = PPC_PAGE_NUMBER(FirstUsablePage) + 1;
}
}
int ignore(int trapCode, ppc_trap_frame_t *trap)
{
return 1;
}
int fpenable(int trapCode, ppc_trap_frame_t *trap)
{
/* Turn on FP */
trap->srr1 |= 8192;
return 1;
}
extern int trap_start[], trap_end[];
void copy_trap_handler(int trap)
{
int i;
paddr_t targetArea = trap * 0x100;
/* Set target addr */
trap_end[0] = (int)_mmumain;
for (i = 0; i <= trap_end - trap_start; i++)
{
SetPhys(targetArea + (i * sizeof(int)), trap_start[i]);
}
}
void initme()
{
int i;
for(i = 0; i < HTABSIZ / sizeof(int); i++)
{
((int *)HTABORG)[i] = 0;
}
/* Default to hang on unknown exception */
for(i = 0; i < 30; i++)
{
callback[i] = (MmuTrapHandler)TakeException;
if (i != 1) /* Preserve reset handler */
copy_trap_handler(i);
}
/* Serial Interrupt */
callback[5] = 0; /* Do nothing until the user asks */
/* Program Exception */
callback[6] = (MmuTrapHandler)TakeException;
/* Floating point exception */
callback[8] = fpenable;
/* Ignore decrementer and EE */
callback[9] = ignore;
/* Single Step */
callback[0x20] = (MmuTrapHandler)TakeException;
}
ppc_map_t *allocpage()
{
MmuFreePage *FreePage = 0;
if (FreeList)
{
if ((void *)FreeList == (void *)PpcPageTable)
{
fmtout("Problem! FreeList: page 0 is free\n");
while(1);
}
FreePage = FreeList;
FreeList = FreeList->next;
((ppc_map_t*)FreePage)->addr = MMU_ADDR_RESERVED;
return ((ppc_map_t*)FreePage);
}
else
{
while(!mmuisfreepage(NextPage) && NextPage < PPC_PAGE_NUMBER(RamSize))
{
NextPage++;
}
if (NextPage < PPC_PAGE_NUMBER(RamSize))
{
if (NextPage < 0x30)
{
fmtout("Problem! NextPage is low (%x)\n", NextPage);
while(1);
}
PpcPageTable[NextPage].addr = MMU_ADDR_RESERVED;
return &PpcPageTable[NextPage++];
}
else
{
return NULL;
}
}
}
void freepage(ppc_map_t *PagePtr)
{
MmuFreePage *FreePage = (MmuFreePage*)PagePtr;
PagePtr->proc = PagePtr->addr = 0;
FreePage->next = FreeList;
FreeList = FreePage;
}
MmuVsidTree *allocvsidtree()
{
if(FreeTree)
{
MmuVsidTree *result = (MmuVsidTree*)FreeTree;
FreeTree = FreeTree->next;
return result;
}
else if(TreeAlloc >= 3 || !NextTreePage)
{
ppc_map_t *map = allocpage();
NextTreePage = (MmuVsidTree*)PPC_PAGE_ADDR((map - PpcPageTable));
TreeAlloc = 1;
return NextTreePage;
}
else
{
return &NextTreePage[TreeAlloc++];
}
}
void freevsidtree(MmuVsidTree *tree)
{
int i;
for(i = 0; i < 256; i++)
if(tree->leaves[i])
freepage(tree->leaves[i]);
MmuFreeTree *NextFreeTree = (MmuFreeTree *)tree;
NextFreeTree->next = FreeTree;
FreeTree = NextFreeTree;
}
void *allocvsid(int vsid)
{
ppc_map_t *map = allocpage();
MmuVsidInfo *info;
if(!map) return 0;
map->pte.pteh = map->pte.ptel = 0;
info = (MmuVsidInfo*)PPC_PAGE_ADDR((map - PpcPageTable));
info->vsid = vsid;
info->next = VsidHead;
VsidHead = info;
return info;
}
void mmuallocvsid(int vsid, int mask)
{
int i;
for(i = 0; i < 16; i++)
{
if(mask & (1 << i))
allocvsid((vsid << 4) + i);
}
}
MmuVsidInfo *findvsid(int vsid)
{
MmuVsidInfo *info;
for(info = VsidHead; info; info = info->next)
{
if(info->vsid == vsid) return info;
}
return 0;
}
void freevsid(int vsid)
{
int i;
MmuVsidInfo *info = findvsid(vsid);
if(!info) return;
ppc_map_t *map = &PpcPageTable[PPC_PAGE_NUMBER((paddr_t)info)];
for(i = 0; i < 256; i++)
{
if(info->tree[i])
freevsidtree(info->tree[i]);
}
freepage(map);
}
void mmufreevsid(int vsid, int mask)
{
int i;
for(i = 0; i < 16; i++)
{
if(mask & (1 << i))
freevsid((vsid << 4) + i);
}
}
int mmuaddpage(ppc_map_info_t *info, int count)
{
int i, iva = 0, vsid, phys, virt;
int ptehi;
int ptelo, vsid_table_hi, vsid_table_lo;
ppc_map_t *PagePtr;
MmuVsidInfo *VsidInfo;
MmuVsidTree *VsidTree;
for(i = 0; i < count; i++)
{
info[i].phys &= ~PPC_PAGE_MASK;
info[i].addr &= ~PPC_PAGE_MASK;
virt = info[i].addr;
vsid = ((info[i].addr >> 28) & 15) | (info[i].proc << 4);
VsidInfo = findvsid(vsid);
if(!VsidInfo) return -1;
ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
if(info[i].phys) {
PagePtr = &PpcPageTable[PPC_PAGE_NUMBER(info[i].phys)];
} else {
PagePtr = allocpage();
if(!PagePtr)
{
return 0;
}
}
phys = PPC_PAGE_ADDR((PagePtr - PpcPageTable));
ptelo = phys & ~PPC_PAGE_MASK;
if (phys < 0x30000)
{
/* Should not be allocating physical */
fmtout("Allocated physical: %x, logical %x\n", phys, virt);
fmtout("PagePtr %x (page %d)\n", PagePtr, i);
fmtout("info [ %x %x %x %x ]\n", info[i].proc, info[i].addr, info[i].flags, info[i].phys);
while(1);
}
/* Update page data */
PagePtr->pte.pteh = ptehi;
PagePtr->pte.ptel = ptelo;
PagePtr->proc = info[i].proc;
PagePtr->addr = virt;
vsid_table_hi = virt >> 20 & 255;
vsid_table_lo = virt >> 12 & 255;
if(!VsidInfo->tree[vsid_table_hi])
VsidInfo->tree[vsid_table_hi] = allocvsidtree();
VsidTree = VsidInfo->tree[vsid_table_hi];
if(!VsidTree) return 0;
VsidTree->leaves[vsid_table_lo] = PagePtr;
__asm__("tlbie %0\n\tsync\n\tisync" : : "r" (iva));
}
return 1;
}
paddr_t mmunewpage()
{
ppc_map_t *PagePtr = allocpage();
if (!PagePtr) return 0;
return PPC_PAGE_ADDR(PagePtr - PpcPageTable);
}
ppc_pteg_t *PtegFromPage(ppc_map_t *map, int hfun)
{
if(!map->proc && !map->addr) return 0;
return &PpcHashedPTE[PtegNumber(map->addr, hfun)];
}
int PageMatch(vaddr_t addr, ppc_pte_t pte)
{
int vsid_pte = (pte.pteh >> 7) & 15, api_pte = pte.pteh & 63;
return
(((addr >> 28) & 15) == vsid_pte) &&
(((addr >> 22) & 63) == api_pte);
}
ppc_map_t *mmuvirtmap(vaddr_t addr)
{
int seg = (addr >> 28) & 15;
MmuVsidInfo *seginfo = Segs[seg];
MmuVsidTree *segtree = 0;
if(!seginfo) return 0;
segtree = seginfo->tree[(addr >> 20) & 255];
if(!segtree) return 0;
return segtree->leaves[(addr >> 12) & 255];
}
void mmudelpage(ppc_map_info_t *info, int count)
{
int i, j, k, ipa;
ppc_map_t *PagePtr;
ppc_pteg_t *PageEntry;
ppc_pte_t ZeroPte = { 0 };
for(i = 0; i < count; i++)
{
if (info[i].phys)
{
ipa = info[i].phys;
PagePtr = &PpcPageTable[ipa];
info[i].proc = PagePtr->proc;
info[i].addr = PagePtr->addr;
}
else
{
PagePtr = mmuvirtmap(info[i].addr);
ipa = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
}
for(j = 0; j < 2; j++)
{
PageEntry = PtegFromPage(PagePtr, j);
for(k = 0; k < 8; k++)
{
if(PageMatch(ipa, PageEntry->block[k]))
{
if(PageEntry->block[k].ptel & 0x100)
info[i].flags |= MMU_PAGE_DIRTY;
PageEntry->block[k] = ZeroPte;
}
}
}
freepage(PagePtr);
__asm__("tlbie %0\n\tsync\n\tisync" : : "r" (info[i].addr));
}
}
void mmugetpage(ppc_map_info_t *info, int count)
{
int i;
ppc_map_t *PagePtr;
for( i = 0; i < count; i++ )
{
if(!info[i].addr && !info[i].proc)
{
PagePtr = &((ppc_map_t*)PAGETAB)[info[i].phys];
info[i].proc = PagePtr->proc;
info[i].addr = PagePtr->addr;
info[i].flags = MMU_ALL_RW;
} else {
vaddr_t addr = info[i].addr;
int vsid = ((addr >> 28) & 15) | (info[i].proc << 4);
PagePtr = mmuvirtmap(info[i].addr);
if(!PagePtr)
info[i].phys = 0;
else
{
info[i].phys = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
info[i].flags = MMU_ALL_RW; // HACK
}
}
}
}
int mmuisfreepage(paddr_t pageno)
{
ppc_map_t *PagePtr = PpcPageTable + pageno;
return !PagePtr->addr;
}
void mmusetvsid(int start, int end, int vsid)
{
int i, sr, s_vsid;
for(i = start; i < end; i++)
{
s_vsid = (vsid << 4) | (i & 15);
sr = (GetSR(i) & ~PPC_VSID_MASK) | s_vsid;
if (Booted)
SetSR(i, sr);
Segs[i] = findvsid(s_vsid);
Vsid[i] = vsid;
}
}
int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr)
{
int hfun = (Clock >> 3) & 1, ptegnum = PtegNumber(addr, hfun);
ppc_map_t *map = mmuvirtmap(addr);
if(!map) return 0;
map->pte.pteh = (map->pte.pteh & ~64) | (hfun << 6);
PpcHashedPTE[ptegnum].block[Clock & 7] = map->pte;
#if 0
fmtout("Reloading addr %x (phys %x) at %x[%x] (%x:%x)\r\n",
addr, PPC_PAGE_ADDR(map - PpcPageTable), ptegnum, Clock & 15,
PpcHashedPTE[ptegnum].block[Clock&7].pteh,
PpcHashedPTE[ptegnum].block[Clock&7].ptel);
#endif
Clock++;
__asm__("tlbie %0\n\tsync\n\tisync" : : "r" (addr));
return 1;
}
void printmap(vaddr_t vaddr, ppc_map_t *map)
{
fmtout("%x: proc %x addr %x\n",
PPC_PAGE_ADDR(map - PpcPageTable),
map->proc, vaddr);
}
void dumptree(vaddr_t vaddr, MmuVsidTree *tree)
{
int j;
for (j = 0; j < 256; j++)
{
if (tree->leaves[j])
{
printmap(vaddr | (j << 12), tree->leaves[j]);
}
}
}
void dumpvsid(MmuVsidInfo *vsid)
{
int i;
fmtout("vsid %d (%x):\n", vsid->vsid>>4, vsid->vsid<<28);
for (i = 0; i < 256; i++)
{
if (vsid->tree[i])
{
dumptree((vsid->vsid<<28) | i << 20, vsid->tree[i]);
}
}
}
void dumpmap()
{
int i,j;
ppc_map_t *map;
MmuVsidInfo *vsid;
fmtout("Address spaces:\n");
for (vsid = VsidHead; vsid; vsid = vsid->next)
{
dumpvsid(vsid);
}
}
void callkernel(void *fun_ptr, void *arg)
{
int i;
Booted = 1;
for (i = 0; i < 16; i++)
{
// Patch up the vsid map. We shouldn't muck with these until we're
// booted.
mmusetvsid(i, i+1, Vsid[i]);
}
void (*fun)(void *) = fun_ptr;
__asm__("mfmsr 3\n\t"
"ori 3,3,0x30\n\t"
"mtmsr 3\n\t"
"mtsdr1 %0\n\t"
"mr 0,%2\n\t"
"mtctr 0\n\t"
"mr 3,%1\n\t"
"bctrl\n\t"
: : "r" (HTABORG), "r" (arg), "r" (fun));
/* BYE ! */
}

View file

@ -1,14 +0,0 @@
#pragma once
void initme(void);
void mmusetramsize(paddr_t size);
int mmuaddpage(ppc_map_info_t *info, int count);
void mmudelpage(ppc_map_info_t *info, int count);
void mmugetpage(ppc_map_info_t *info, int count);
void mmusetvsid(int start, int end, int vsid);
void *allocvsid(int);
void mmuallocvsid(int vsid, int mask);
void freevsid(int);
void mmufreevsid(int vsid, int mask);
int mmunitest(void);
void callkernel(void *fun_ptr, void *arg);

View file

@ -1,23 +0,0 @@
#include "ppcmmu/mmu.h"
#include "ppcmmu/mmuutil.h"
#include "mmuobject.h"
int mmunitest()
{
int ret;
int (*fun)(int ret) = (void *)0x80000000;
ppc_map_info_t info = { 0 };
volatile int oldmsr, msr = 0x2030;
__asm__("mfmsr 0\n\tstw 0,0(%0)" : : "r" (&oldmsr));
mmusetvsid(8, 9, 0);
info.flags = MMU_ALL_RW;
info.proc = 0;
info.addr = (vaddr_t)fun;
mmuaddpage(&info, 1);
__asm__("mtmsr %0" : : "r" (msr));
__asm__("mtsdr1 %0" : : "r" (HTABORG));
*((int *)fun) = 0x4e800020;
ret = fun(3);
__asm__("mtmsr %0" : : "r" (oldmsr));
return ret != 3;
}

View file

@ -1,411 +0,0 @@
#include "ppcmmu/mmu.h"
#include "ppcmmu/mmuutil.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 = 0;
switch( n ) {
case 0:
__asm__("mfsr %0,0" : "=r" (res));
break;
case 1:
__asm__("mfsr %0,1" : "=r" (res));
break;
case 2:
__asm__("mfsr %0,2" : "=r" (res));
break;
case 3:
__asm__("mfsr %0,3" : "=r" (res));
break;
case 4:
__asm__("mfsr %0,4" : "=r" (res));
break;
case 5:
__asm__("mfsr %0,5" : "=r" (res));
break;
case 6:
__asm__("mfsr %0,6" : "=r" (res));
break;
case 7:
__asm__("mfsr %0,7" : "=r" (res));
break;
case 8:
__asm__("mfsr %0,8" : "=r" (res));
break;
case 9:
__asm__("mfsr %0,9" : "=r" (res));
break;
case 10:
__asm__("mfsr %0,10" : "=r" (res));
break;
case 11:
__asm__("mfsr %0,11" : "=r" (res));
break;
case 12:
__asm__("mfsr %0,12" : "=r" (res));
break;
case 13:
__asm__("mfsr %0,13" : "=r" (res));
break;
case 14:
__asm__("mfsr %0,14" : "=r" (res));
break;
case 15:
__asm__("mfsr %0,15" : "=r" (res));
break;
}
return res;
}
inline void SetSR(int n, int val) {
switch( n ) {
case 0:
__asm__("mtsr 0,%0" : : "r" (val));
break;
case 1:
__asm__("mtsr 1,%0" : : "r" (val));
break;
case 2:
__asm__("mtsr 2,%0" : : "r" (val));
break;
case 3:
__asm__("mtsr 3,%0" : : "r" (val));
break;
case 4:
__asm__("mtsr 4,%0" : : "r" (val));
break;
case 5:
__asm__("mtsr 5,%0" : : "r" (val));
break;
case 6:
__asm__("mtsr 6,%0" : : "r" (val));
break;
case 7:
__asm__("mtsr 7,%0" : : "r" (val));
break;
case 8:
__asm__("mtsr 8,%0" : : "r" (val));
break;
case 9:
__asm__("mtsr 9,%0" : : "r" (val));
break;
case 10:
__asm__("mtsr 10,%0" : : "r" (val));
break;
case 11:
__asm__("mtsr 11,%0" : : "r" (val));
break;
case 12:
__asm__("mtsr 12,%0" : : "r" (val));
break;
case 13:
__asm__("mtsr 13,%0" : : "r" (val));
break;
case 14:
__asm__("mtsr 14,%0" : : "r" (val));
break;
case 15:
__asm__("mtsr 15,%0" : : "r" (val));
break;
}
}
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;
}
#define BATSET(n,t) \
case n: __asm__("mt" #t "batu " #n ",%0\n\tmt" #t "batl " #n ",%1" \
: : "r" (batHi), "r" (batLo)); break;
void SetBat( int bat, int inst, int batHi, int batLo ) {
if( inst ) {
switch( bat ) {
BATSET(0,i);
BATSET(1,i);
BATSET(2,i);
BATSET(3,i);
}
} else {
switch( bat ) {
BATSET(0,d);
BATSET(1,d);
BATSET(2,d);
BATSET(3,d);
}
}
__asm__("isync\n\tsync");
}
inline int GetSDR1() {
register int res asm("r3");
__asm__("mfsdr1 3");
return res;
}
inline void SetSDR1( int sdr ) {
int i,j;
__asm__("mtsdr1 3");
__asm__("sync");
__asm__("isync");
for( i = 0; i < 256; i++ ) {
j = i << 12;
__asm__("tlbie %0,0" : : "r" (j));
}
__asm__("eieio");
__asm__("tlbsync");
__asm__("ptesync");
}
inline int BatTranslate( int batu, int batl, int virt ) {
int mask;
if(batu & 0x3fc)
{
mask = ~(0x1ffff | ((batu & 0x3fc)>>2)<<17);
if((batu & 2) && ((batu & mask) == (virt & mask)))
return (batl & mask) | (virt & ~mask);
} else {
mask = ~(0x1ffff | (batl << 17));
if(!(batl & 0x40) || ((batu & mask) != (virt & mask)))
return (batl & mask) | (virt & ~mask);
}
return -1;
}
inline int BatHit( int batu, int batl, int virt ) {
return BatTranslate( batu, batl, virt ) != -1;
}
/* translate address */
int PpcVirt2phys( vaddr_t virt, int inst ) {
int msr = GetMSR();
int txmask = inst ? 0x20 : 0x10;
int i, bath, batl, sr, sdr1, physbase, vahi, valo;
int npteg, hash, hashmask, ptehi, ptelo, ptegaddr;
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;
}
}
int PtegNumber(vaddr_t virt, int hfun)
{
int sr = GetSR( (virt >> 28) & 0xf );
int vsid = sr & PPC_VSID_MASK;
return ((((vsid & 0x7ffff) ^ ((virt >> 12) & 0xffff)) ^ (hfun ? -1 : 0)) & ((HTABSIZ - 1) >> 3) & 0x3ff);
}

View file

@ -43,8 +43,6 @@ else()
i386/framebased-gcchack-asm.S)
elseif(ARCH STREQUAL "amd64")
list(APPEND SOURCE amd64/framebased.S)
elseif(ARCH STREQUAL "powerpc")
list(APPEND SOURCE powerpc/framebased.S)
endif()
add_library(pseh ${SOURCE} ${ASM_SOURCE})

View file

@ -1,69 +0,0 @@
// Copyright (c) 2004/2005 KJK::Hyperion
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to dos so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.text
.globl _SEHCleanHandlerEnvironment
_SEHCleanHandlerEnvironment:
blr
.globl _SEHCurrentRegistration
_SEHCurrentRegistration:
lwz 3,0(13)
blr
// R3: Frame to store in
.globl _SEHRegisterFrame
_SEHRegisterFrame:
lwz 4,0(13)
stw 3,0(13)
stw 4,0(3)
blr
.globl _SEHUnregisterFrame
_SEHUnregisterFrame:
lwz 3,0(13)
lwz 3,0(3)
stw 3,0(13)
blr
.globl _SEHGlobalUnwind
_SEHGlobalUnwind:
.extern _SEHRtlUnwind
// RtlUnwind clobbers all the "don't clobber" registers, so we save them
lwz 3,4(1)
stwu 1,-132(1)
stmw 2,-128(1)
xor 6,6,6
xor 5,5,5
lis 4,.RestoreRegisters@ha
addi 4,4,.RestoreRegisters@l # Where to jump back to
# We already have r3
bl _SEHRtlUnwind
.RestoreRegisters:
lmw 2,-128(1)
addi 1,1,132
blr
// EOF

View file

@ -104,16 +104,6 @@ elseif(ARCH STREQUAL "arm")
arm/except.c
byteswap.c
mem.c)
elseif(ARCH STREQUAL "powerpc")
list(APPEND ASM_SOURCE
powerpc/rtlmem.s
powerpc/rtlswap.s)
list(APPEND SOURCE
byteswap.c
powerpc/debug.c
powerpc/except.c
powerpc/interlocked.c
powerpc/thread.c)
endif()
add_asm_files(rtl_asm ${ASM_SOURCE})

View file

@ -1,41 +0,0 @@
#include <ntddk.h>
#include <winddk.h>
NTKERNELAPI
VOID
DbgBreakPoint() { __asm__("ti 31,0,0"); }
NTKERNELAPI
VOID
DbgBreakPointWithStatus(ULONG Status) { __asm__("ti 31,0,0"); }
ULONG
NTAPI
DebugService
(ULONG Service, PVOID Argument1, PVOID Argument1, PVOID Argument3, PVOID Argument4)
{
ULONG Result;
__asm__("mr 0,%1\n\t"
"mr 3,%2\n\t"
"mr 4,%3\n\t"
"mr 5,%4\n\t"
"mr 6,%5\n\t"
"mr 7,%6\n\t"
"sc\n\t"
"mr %0,3\n\t" :
"=r" (Result) :
"r" (0x10000),
"r" (Service),
"r" (Argument1),
"r" (Argument2),
"r" (Argument3),
"r" (Argument4) );
return Result;
}
VOID
NTAPI
DebugService2
(PVOID Arg1, PVOID Arg2, ULONG Service)
{
}

View file

@ -1,54 +0,0 @@
/* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Runtime Library
* PURPOSE: User-Mode Exception Support
* FILE: lib/rtl/powerpc/except.c
* PROGRAMERS: Alex Ionescu (alex@relsoft.net)
* David Welch <welch@cwcom.net>
* Skywing <skywing@valhallalegends.com>
* KJK::Hyperion <noog@libero.it>
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
NTSYSAPI
VOID
NTAPI
RtlCaptureContext
(OUT PCONTEXT ContextRecord)
{
// XXX arty fixme
}
NTSYSAPI
BOOLEAN
NTAPI
RtlDispatchException
(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
{
// XXX arty fixme
return TRUE;
}
VOID
NTAPI
RtlUnwind(IN PVOID TargetFrame OPTIONAL,
IN PVOID TargetIp OPTIONAL,
IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
IN PVOID ReturnValue)
{
// XXX arty fixme
}
NTSYSAPI
VOID
NTAPI
RtlGetCallersAddress(
OUT PVOID *CallersAddress,
OUT PVOID *CallersCaller)
{
}

View file

@ -1,128 +0,0 @@
typedef unsigned int size_t;
#include <ntddk.h>
#include <winddk.h>
#include <string.h>
#include <intrin.h>
NTKERNELAPI
LONG
FASTCALL
InterlockedExchange(
LONG volatile *Target, LONG Value)
{
return _InterlockedExchange(Target, Value);
}
NTKERNELAPI
LONG
FASTCALL
InterlockedExchangeAdd(
LONG volatile *Target, LONG Value)
{
return _InterlockedExchangeAdd(Target, Value);
}
NTKERNELAPI
LONG
WINAPI
InterlockedCompareExchange(
LONG volatile *Destination,
LONG Exchange, LONG Comparand)
{
return _InterlockedCompareExchange(Destination, Exchange, Comparand);
}
NTKERNELAPI
LONG
FASTCALL
InterlockedIncrement
(IN OUT LONG volatile *Addend)
{
return _InterlockedIncrement(Addend);
}
NTKERNELAPI
LONG
FASTCALL
InterlockedDecrement(
IN OUT LONG volatile *Addend)
{
return _InterlockedDecrement(Addend);
}
PSLIST_ENTRY
WINAPI
InterlockedPopEntrySList(
PSLIST_HEADER ListHead)
{
PSLIST_ENTRY Result = NULL;
KIRQL OldIrql;
static BOOLEAN GLLInit = FALSE;
static KSPIN_LOCK GlobalListLock;
if(!GLLInit)
{
KeInitializeSpinLock(&GlobalListLock);
GLLInit = TRUE;
}
KeAcquireSpinLock(&GlobalListLock, &OldIrql);
if(ListHead->Next.Next)
{
Result = ListHead->Next.Next;
ListHead->Next.Next = Result->Next;
}
KeReleaseSpinLock(&GlobalListLock, OldIrql);
return Result;
}
NTKERNELAPI
PSLIST_ENTRY
FASTCALL
InterlockedPushEntrySList(
IN PSLIST_HEADER ListHead,
IN PSLIST_ENTRY ListEntry)
{
PVOID PrevValue;
do
{
PrevValue = ListHead->Next.Next;
ListEntry->Next = PrevValue;
}
while (InterlockedCompareExchangePointer(&ListHead->Next.Next,
ListEntry,
PrevValue) != PrevValue);
return (PSLIST_ENTRY)PrevValue;
}
NTKERNELAPI
VOID
FASTCALL
ExInterlockedAddLargeStatistic(
IN PLARGE_INTEGER Addend,
IN ULONG Increment)
{
_InterlockedAddLargeStatistic(&Addend->QuadPart, Increment);
}
NTKERNELAPI
LONGLONG
FASTCALL
ExInterlockedCompareExchange64(
IN OUT PLONGLONG Destination,
IN PLONGLONG Exchange,
IN PLONGLONG Comparand,
IN PKSPIN_LOCK Lock)
{
KIRQL OldIrql;
LONGLONG Result;
KeAcquireSpinLock(Lock, &OldIrql);
Result = *Destination;
if(*Destination == Result)
*Destination = *Exchange;
KeReleaseSpinLock(Lock, OldIrql);
return Result;
}

View file

@ -1,101 +0,0 @@
/*
*
*/
.globl RtlCompareMemory
.globl RtlCompareMemoryUlong
.globl RtlFillMemory
.globl RtlFillMemoryUlong
.globl RtlFillMemoryUlonglong
.globl RtlMoveMemory
.globl RtlZeroMemory
RtlCompareMemory:
1:
mr 0,5
cmpwi 0,5,4
blt 2f
lwz 6,0(3)
lwz 7,0(3)
addi 6,6,-7
cmpwi 0,6,0
bne 2f
addi 3,3,4
addi 4,4,4
subi 5,5,4
b 1b
2:
cmpwi 0,5,0
beq 3f
lbz 6,0(3)
lbz 7,0(4)
addi 6,6,-7
cmpwi 0,6,0
bne 3f
addi 3,3,1
addi 4,4,1
subi 5,5,1
b 2b
3:
mr 4,0
sub 3,4,5
blr
RtlCompareMemoryUlong:
or 6,3,4
or 6,6,5
andi. 6,6,3
bne RtlCompareMemory
xor 3,3,3
blr
RtlFillMemory:
rlwinm 6,5,8,0xff00
rlwinm 7,5,0,0xff
or 7,6,7
rlwinm 5,7,16,0xffff0000
or 5,7,5
1:
cmpwi 0,4,4
blt 2f
stw 5,0(3)
addi 3,3,4
subi 4,4,4
b 1b
2:
cmpwi 0,4,0
beq 3f
stb 5,0(3)
addi 3,3,1
subi 4,4,1
b 2b
3:
blr
RtlFillMemoryUlong:
b RtlFillMemory
RtlFillMemoryUlonglong:
b RtlFillMemoryUlong
RtlMoveMemory:
b memmove
RtlZeroMemory:
mr 5,4
xor 4,4,4
b memset

View file

@ -1,41 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Byte swap functions
* FILE: lib/rtl/powerpc/rtlswap.s
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
.globl RtlUshortByteSwap
.globl RtlUlongByteSwap
.globl RtlUlonglongByteSwap
/* FUNCTIONS ***************************************************************/
RtlUshortByteSwap:
/* Swap high and low bits */
rlwinm 4,3,24,0xff
rlwinm 5,3,8,0xff00
or 3,4,5
blr
RtlUlongByteSwap:
rlwinm 4,3,8,0xff
rlwinm 5,3,24,0xff000000
or 4,4,5
rlwinm 5,3,8,0xff0000
rlwinm 3,3,24,0xff00
or 3,4,5
or 3,3,6
blr
RtlUlonglongByteSwap:
stwu 1,16(1)
stw 4,4(1)
bl RtlUlongByteSwap
stw 3,4(1)
lwz 3,4(1)
bl RtlUlongByteSwap
lwz 4,4(1)
subi 1,1,16
blr

View file

@ -1,38 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Rtl user thread functions
* FILE: lib/rtl/powerpc/thread.c
* PROGRAMERS:
* Alex Ionescu (alex@relsoft.net)
* Eric Kohl
* KJK::Hyperion
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#include "i386/ketypes.h"
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS *******************************************************/
/*
* @implemented
*/
VOID
NTAPI
RtlInitializeContext(IN HANDLE ProcessHandle,
OUT PCONTEXT ThreadContext,
IN PVOID ThreadStartParam OPTIONAL,
IN PTHREAD_START_ROUTINE ThreadStartAddress,
IN PINITIAL_TEB InitialTeb)
{
DPRINT("RtlInitializeContext: (hProcess: %p, ThreadContext: %p, Teb: %p\n",
ProcessHandle, ThreadContext, InitialTeb);
// XXX arty fixme
}
/* EOF */