mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33:31 +08:00
[FREELDR][NTOS][HALPPC][SDK] Remove PowerPC code
Remove PowerPC-related code from the kernel, HAL, SDK and Freeloader.
This commit is contained in:
parent
911fc3cf5b
commit
6ef6fabfc5
@ -1,111 +0,0 @@
|
||||
.section ".text"
|
||||
.extern PpcInit
|
||||
.globl _start
|
||||
.globl call_ofw
|
||||
_start:
|
||||
sync
|
||||
isync
|
||||
|
||||
lis %r1,stackend@ha
|
||||
addi %r1,%r1,stackend@l
|
||||
|
||||
/* Store ofw call addr */
|
||||
mr %r21,%r5
|
||||
lis %r10,ofw_call_addr@ha
|
||||
stw %r5,ofw_call_addr@l(%r10)
|
||||
|
||||
bl zero_registers
|
||||
|
||||
/* Zero CTR */
|
||||
mtcr %r31
|
||||
|
||||
lis %r3,PpcInit@ha
|
||||
addi %r3,%r3,PpcInit@l
|
||||
mtlr %r3
|
||||
|
||||
/* Check for ofw */
|
||||
lis %r3,ofw_call_addr@ha
|
||||
lwz %r3,ofw_call_addr@l(%r3)
|
||||
cmpw %r3,%r31 /* Zero? */
|
||||
mr %r3,%r31
|
||||
beq initfp
|
||||
|
||||
lis %r3,call_ofw@ha
|
||||
addi %r3,%r3,call_ofw@l
|
||||
b bootme
|
||||
|
||||
initfp:
|
||||
/* Enabling FP at this point won't hurt, and the varargs scheme we're
|
||||
* using now requires it. */
|
||||
mfmsr %r0
|
||||
ori %r0,%r0,8192
|
||||
mtmsr %r0
|
||||
|
||||
bootme:
|
||||
blr
|
||||
|
||||
zero_registers:
|
||||
xor %r2,%r2,%r2
|
||||
mr %r0,%r2
|
||||
mr %r3,%r2
|
||||
|
||||
mr %r4,%r2
|
||||
mr %r5,%r2
|
||||
mr %r6,%r2
|
||||
mr %r7,%r2
|
||||
|
||||
mr %r8,%r2
|
||||
mr %r9,%r2
|
||||
mr %r10,%r2
|
||||
mr %r11,%r2
|
||||
|
||||
mr %r12,%r2
|
||||
mr %r13,%r2
|
||||
mr %r14,%r2
|
||||
mr %r15,%r2
|
||||
|
||||
mr %r12,%r2
|
||||
mr %r13,%r2
|
||||
mr %r14,%r2
|
||||
mr %r15,%r2
|
||||
|
||||
mr %r16,%r2
|
||||
mr %r17,%r2
|
||||
mr %r18,%r2
|
||||
mr %r19,%r2
|
||||
|
||||
mr %r20,%r2
|
||||
mr %r21,%r2
|
||||
mr %r22,%r2
|
||||
mr %r23,%r2
|
||||
|
||||
mr %r24,%r2
|
||||
mr %r25,%r2
|
||||
mr %r26,%r2
|
||||
mr %r27,%r2
|
||||
|
||||
mr %r28,%r2
|
||||
mr %r29,%r2
|
||||
mr %r30,%r2
|
||||
mr %r31,%r2
|
||||
|
||||
blr
|
||||
|
||||
ofw_memory_size:
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
|
||||
.align 4
|
||||
stack:
|
||||
.space 0x4000
|
||||
stackend:
|
||||
.long 0,0,0,0
|
||||
|
||||
.globl _bss
|
||||
.section ".bss2"
|
||||
_bss:
|
||||
.long 0
|
||||
|
||||
.align 4
|
@ -1,105 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define __init
|
||||
#define __initdata
|
||||
|
||||
#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
|
||||
#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
|
||||
#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
|
||||
#define SPRN_LDSTDB 0x3f4 /* */
|
||||
#define SPRN_LR 0x008 /* Link Register */
|
||||
#ifndef SPRN_PIR
|
||||
#define SPRN_PIR 0x3FF /* Processor Identification Register */
|
||||
#endif
|
||||
#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
|
||||
#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
|
||||
#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
|
||||
#define SPRN_PVR 0x11F /* Processor Version Register */
|
||||
#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
|
||||
#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
|
||||
#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
|
||||
#define SPRN_ASR 0x118 /* Address Space Register */
|
||||
#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
|
||||
#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
|
||||
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
|
||||
#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
|
||||
#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
|
||||
#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
|
||||
#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
|
||||
#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
|
||||
#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
|
||||
#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
|
||||
#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
|
||||
#ifndef SPRN_SVR
|
||||
#define SPRN_SVR 0x11E /* System Version Register */
|
||||
#endif
|
||||
#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */
|
||||
/* these bits were defined in inverted endian sense originally, ugh, confusing */
|
||||
|
||||
/* Values for PP (assumes Ks=0, Kp=1) */
|
||||
#define PP_RWXX 0 /* Supervisor read/write, User none */
|
||||
#define PP_RWRX 1 /* Supervisor read/write, User read */
|
||||
#define PP_RWRW 2 /* Supervisor read/write, User read/write */
|
||||
#define PP_RXRX 3 /* Supervisor read, User read */
|
||||
|
||||
/* Block size masks */
|
||||
#define BL_128K 0x000
|
||||
#define BL_256K 0x001
|
||||
#define BL_512K 0x003
|
||||
#define BL_1M 0x007
|
||||
#define BL_2M 0x00F
|
||||
#define BL_4M 0x01F
|
||||
#define BL_8M 0x03F
|
||||
#define BL_16M 0x07F
|
||||
#define BL_32M 0x0FF
|
||||
#define BL_64M 0x1FF
|
||||
#define BL_128M 0x3FF
|
||||
#define BL_256M 0x7FF
|
||||
|
||||
/* BAT Access Protection */
|
||||
#define BPP_XX 0x00 /* No access */
|
||||
#define BPP_RX 0x01 /* Read only */
|
||||
#define BPP_RW 0x02 /* Read/write */
|
||||
|
||||
/* Definitions for 40x embedded chips. */
|
||||
#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
|
||||
#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
|
||||
#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
|
||||
#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
|
||||
#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
|
||||
#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
|
||||
#define _PAGE_RW 0x040 /* software: Writes permitted */
|
||||
#define _PAGE_DIRTY 0x080 /* software: dirty page */
|
||||
#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
|
||||
#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
|
||||
#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
|
||||
|
||||
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
|
||||
#define _PMD_BAD 0x802
|
||||
#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
|
||||
#define _PMD_SIZE_4M 0x0c0
|
||||
#define _PMD_SIZE_16M 0x0e0
|
||||
#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
|
||||
|
||||
#define PVR_VER(pvr)(((pvr) >> 16) & 0xFFFF) /* Version field */
|
||||
|
||||
#define KERNELBASE 0x80000000
|
||||
|
||||
typedef unsigned char __u8;
|
||||
typedef unsigned short __u16;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
typedef struct _pci_reg_property {
|
||||
struct {
|
||||
int a_hi, a_mid, a_lo;
|
||||
} addr;
|
||||
int size_hi, size_lo;
|
||||
} pci_reg_property;
|
||||
|
||||
void btext_drawstring(const char *c);
|
||||
void btext_drawhex(unsigned long v);
|
||||
|
||||
void *ioremap(__u32 phys, __u32 size);
|
||||
void iounmap(void *logical);
|
||||
|
||||
__u32 GetPVR(void);
|
@ -1,348 +0,0 @@
|
||||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#define _NTSYSTEM_
|
||||
#include <freeldr.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#define DbgPrint printf
|
||||
|
||||
extern PVOID KernelBase;
|
||||
extern PVOID KernelMemory;
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
LdrPEGetExportByName(PVOID BaseAddress,
|
||||
PUCHAR SymbolName,
|
||||
USHORT Hint);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PLOADER_MODULE
|
||||
NTAPI
|
||||
LdrGetModuleObject(PCHAR ModuleName)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < LoaderBlock.ModsCount; i++)
|
||||
{
|
||||
if (strstr(_strupr((PCHAR)reactos_modules[i].String), _strupr(ModuleName)))
|
||||
{
|
||||
return &reactos_modules[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
LdrPEFixupForward(IN PCHAR ForwardName)
|
||||
{
|
||||
CHAR NameBuffer[128];
|
||||
PCHAR p;
|
||||
PLOADER_MODULE ModuleObject;
|
||||
|
||||
strcpy(NameBuffer, ForwardName);
|
||||
p = strchr(NameBuffer, '.');
|
||||
if (p == NULL) return NULL;
|
||||
*p = 0;
|
||||
|
||||
ModuleObject = LdrGetModuleObject(NameBuffer);
|
||||
if (!ModuleObject)
|
||||
{
|
||||
DbgPrint("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return LdrPEGetExportByName((PVOID)ModuleObject->ModStart, (PUCHAR)(p + 1), 0xffff);
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
LdrPEGetExportByName(PVOID BaseAddress,
|
||||
PUCHAR SymbolName,
|
||||
USHORT Hint)
|
||||
{
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||
PULONG * ExFunctions;
|
||||
PULONG * ExNames;
|
||||
USHORT * ExOrdinals;
|
||||
PVOID ExName;
|
||||
ULONG Ordinal;
|
||||
PVOID Function;
|
||||
LONG minn, maxn, mid, res;
|
||||
ULONG ExportDirSize;
|
||||
|
||||
/* HAL and NTOS use a virtual address, switch it to physical mode */
|
||||
if ((ULONG_PTR)BaseAddress & 0x80000000)
|
||||
{
|
||||
BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - KSEG0_BASE + (ULONG)KernelMemory);
|
||||
}
|
||||
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
RtlImageDirectoryEntryToData(BaseAddress,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&ExportDirSize);
|
||||
if (!ExportDir)
|
||||
{
|
||||
DbgPrint("LdrPEGetExportByName(): no export directory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The symbol names may be missing entirely */
|
||||
if (!ExportDir->AddressOfNames)
|
||||
{
|
||||
DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get header pointers
|
||||
*/
|
||||
ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
|
||||
ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
|
||||
ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
|
||||
|
||||
/*
|
||||
* Check the hint first
|
||||
*/
|
||||
if (Hint < ExportDir->NumberOfNames)
|
||||
{
|
||||
ExName = RVA(BaseAddress, ExNames[Hint]);
|
||||
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
|
||||
{
|
||||
Ordinal = ExOrdinals[Hint];
|
||||
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
|
||||
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
|
||||
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
|
||||
{
|
||||
Function = LdrPEFixupForward((PCHAR)Function);
|
||||
if (Function == NULL)
|
||||
{
|
||||
DbgPrint("LdrPEGetExportByName(): failed to find %s\n", Function);
|
||||
}
|
||||
return Function;
|
||||
}
|
||||
|
||||
if (Function != NULL) return Function;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary search
|
||||
*/
|
||||
minn = 0;
|
||||
maxn = ExportDir->NumberOfNames - 1;
|
||||
while (minn <= maxn)
|
||||
{
|
||||
mid = (minn + maxn) / 2;
|
||||
|
||||
ExName = RVA(BaseAddress, ExNames[mid]);
|
||||
res = strcmp(ExName, (PCHAR)SymbolName);
|
||||
if (res == 0)
|
||||
{
|
||||
Ordinal = ExOrdinals[mid];
|
||||
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
|
||||
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
|
||||
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
|
||||
{
|
||||
Function = LdrPEFixupForward((PCHAR)Function);
|
||||
if (Function == NULL)
|
||||
{
|
||||
DbgPrint("1: failed to find %s\n", Function);
|
||||
}
|
||||
return Function;
|
||||
}
|
||||
if (Function != NULL)
|
||||
{
|
||||
return Function;
|
||||
}
|
||||
}
|
||||
else if (res > 0)
|
||||
{
|
||||
maxn = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
minn = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back on unsorted */
|
||||
minn = 0;
|
||||
maxn = ExportDir->NumberOfNames - 1;
|
||||
while (minn <= maxn)
|
||||
{
|
||||
ExName = RVA(BaseAddress, ExNames[minn]);
|
||||
res = strcmp(ExName, (PCHAR)SymbolName);
|
||||
if (res == 0)
|
||||
{
|
||||
Ordinal = ExOrdinals[minn];
|
||||
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
|
||||
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
|
||||
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
|
||||
{
|
||||
Function = LdrPEFixupForward((PCHAR)Function);
|
||||
if (Function == NULL)
|
||||
{
|
||||
DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
|
||||
}
|
||||
return Function;
|
||||
}
|
||||
if (Function != NULL)
|
||||
{
|
||||
return Function;
|
||||
}
|
||||
DbgPrint("Failed to get function %s\n", SymbolName);
|
||||
}
|
||||
minn++;
|
||||
}
|
||||
|
||||
DbgPrint("2: failed to find %s\n",SymbolName);
|
||||
return (PVOID)NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
|
||||
PLOADER_MODULE LoaderModule,
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
|
||||
{
|
||||
PVOID* ImportAddressList;
|
||||
PULONG FunctionNameList;
|
||||
|
||||
if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Get the import address list. */
|
||||
ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
|
||||
|
||||
/* Get the list of functions to import. */
|
||||
if (ImportModuleDirectory->OriginalFirstThunk != 0)
|
||||
{
|
||||
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
|
||||
}
|
||||
|
||||
/* Walk through function list and fixup addresses. */
|
||||
while (*FunctionNameList != 0L)
|
||||
{
|
||||
if ((*FunctionNameList) & 0x80000000)
|
||||
{
|
||||
DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
IMAGE_IMPORT_BY_NAME *pe_name;
|
||||
pe_name = RVA(DriverBase, *FunctionNameList);
|
||||
*ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);
|
||||
|
||||
/* Fixup the address to be virtual */
|
||||
*ImportAddressList = (PVOID)(ULONG_PTR)*ImportAddressList + (ULONG_PTR)KernelBase - (ULONG_PTR)KernelMemory;
|
||||
|
||||
|
||||
//DbgPrint("Looked for: %s and found: %x\n", pe_name->Name, *ImportAddressList);
|
||||
if ((*ImportAddressList) == NULL)
|
||||
{
|
||||
DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
ImportAddressList++;
|
||||
FunctionNameList++;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrPEGetOrLoadModule(IN PCHAR ModuleName,
|
||||
IN PCHAR ImportedName,
|
||||
IN PLOADER_MODULE* ImportedModule)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
*ImportedModule = LdrGetModuleObject(ImportedName);
|
||||
if (*ImportedModule == NULL)
|
||||
{
|
||||
/*
|
||||
* For now, we only support import-loading the HAL.
|
||||
* Later, FrLdrLoadDriver should be made to share the same
|
||||
* code, and we'll just call it instead.
|
||||
*/
|
||||
FrLdrLoadDriver(ImportedName, 0);
|
||||
|
||||
/* Return the new module */
|
||||
*ImportedModule = LdrGetModuleObject(ImportedName);
|
||||
if (*ImportedModule == NULL)
|
||||
{
|
||||
DbgPrint("Error loading import: %s\n", ImportedName);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrPEFixupImports(IN PVOID DllBase,
|
||||
IN PCHAR DllName)
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
|
||||
PCHAR ImportedName;
|
||||
NTSTATUS Status;
|
||||
PLOADER_MODULE ImportedModule;
|
||||
ULONG Size;
|
||||
|
||||
/* Process each import module */
|
||||
ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
|
||||
RtlImageDirectoryEntryToData(DllBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT,
|
||||
&Size);
|
||||
while (ImportModuleDirectory && ImportModuleDirectory->Name)
|
||||
{
|
||||
/* Check to make sure that import lib is kernel */
|
||||
ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
|
||||
//DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName);
|
||||
|
||||
Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
//DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName);
|
||||
ImportModuleDirectory++;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
@ -1,555 +0,0 @@
|
||||
/*
|
||||
* FreeLoader PowerPC Part
|
||||
* Copyright (C) 2005 Art Yerkes
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "freeldr.h"
|
||||
#include "machine.h"
|
||||
#include "ppcmmu/mmu.h"
|
||||
#include "of.h"
|
||||
#include "prep.h"
|
||||
#include "compat.h"
|
||||
|
||||
extern void BootMain( PSTR CmdLine );
|
||||
extern ULONG CacheSizeLimit;
|
||||
of_proxy ofproxy;
|
||||
void *PageDirectoryStart, *PageDirectoryEnd;
|
||||
static int chosen_package, stdin_handle, stdout_handle, part_handle = -1;
|
||||
int mmu_handle = 0;
|
||||
int claimed[4];
|
||||
BOOLEAN AcpiPresent = FALSE;
|
||||
CHAR FrLdrBootPath[MAX_PATH] = "", BootPart[MAX_PATH] = "", CmdLine[MAX_PATH] = "bootprep";
|
||||
jmp_buf jmp;
|
||||
volatile char *video_mem = 0;
|
||||
|
||||
void PpcOfwPutChar( int ch ) {
|
||||
char buf[3];
|
||||
if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; }
|
||||
else { buf[0] = ch; buf[1] = 0; }
|
||||
buf[2] = 0;
|
||||
ofw_write(stdout_handle, buf, strlen(buf));
|
||||
}
|
||||
|
||||
int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
|
||||
static char buf[256];
|
||||
int next = 0;
|
||||
int gotname = 0;
|
||||
int match = 0;
|
||||
int i;
|
||||
|
||||
next = ofw_child( parent );
|
||||
|
||||
//printf( "next = %x\n", next );
|
||||
|
||||
gotname = ofw_getprop(parent, "name", buf, 256);
|
||||
|
||||
//printf( "gotname = %d\n", gotname );
|
||||
|
||||
match = !strncmp(buf, devname, strlen(devname));
|
||||
|
||||
if( !nth && match ) return parent;
|
||||
|
||||
for( i = 0; i < depth; i++ ) PpcOfwPutChar( ' ' );
|
||||
|
||||
if( depth == 1 ) {
|
||||
if( gotname > 0 ) {
|
||||
printf( "%c Name: %s\n", match ? '*' : ' ', buf );
|
||||
} else {
|
||||
printf( "- No name attribute for %x\n", parent );
|
||||
}
|
||||
}
|
||||
|
||||
while( !match && next ) {
|
||||
i = PpcFindDevice( depth+1, next, devname, nth );
|
||||
if( i ) return i;
|
||||
next = ofw_peer( next );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOLEAN PpcConsKbHit() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int PpcConsGetCh() {
|
||||
char buf;
|
||||
ofw_read( stdin_handle, &buf, 1 );
|
||||
return buf;
|
||||
}
|
||||
|
||||
void PpcVideoClearScreen( UCHAR Attr ) {
|
||||
}
|
||||
|
||||
VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
|
||||
*Width = 80;
|
||||
*Height = 25;
|
||||
*Depth = 16;
|
||||
}
|
||||
|
||||
ULONG PpcVideoGetBufferSize() {
|
||||
ULONG Width, Height, Depth;
|
||||
MachVideoGetDisplaySize( &Width, &Height, &Depth );
|
||||
return Width * Height * Depth / 8;
|
||||
}
|
||||
|
||||
VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
|
||||
//printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
|
||||
if( Init && !video_mem ) {
|
||||
video_mem = MmAllocateMemory( PpcVideoGetBufferSize() );
|
||||
}
|
||||
return VideoTextMode;
|
||||
}
|
||||
|
||||
VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) {
|
||||
printf("SetTextCursorPosition(%d,%d)\n", X,Y);
|
||||
}
|
||||
|
||||
VOID PpcVideoHideShowTextCursor( BOOLEAN Show ) {
|
||||
printf("HideShowTextCursor(%s)\n", Show ? "true" : "false");
|
||||
}
|
||||
|
||||
VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) {
|
||||
printf( "\033[%d;%dH%c", Y, X, Ch );
|
||||
}
|
||||
|
||||
VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
|
||||
int i,j;
|
||||
ULONG w,h,d;
|
||||
PCHAR ChBuf = Buffer;
|
||||
int offset = 0;
|
||||
|
||||
MachVideoGetDisplaySize( &w, &h, &d );
|
||||
|
||||
for( i = 0; i < h; i++ ) {
|
||||
for( j = 0; j < w; j++ ) {
|
||||
offset = (j * 2) + (i * w * 2);
|
||||
if( ChBuf[offset] != video_mem[offset] ) {
|
||||
video_mem[offset] = ChBuf[offset];
|
||||
MachVideoPutChar(ChBuf[offset],0,j+1,i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN PpcVideoIsPaletteFixed() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID PpcVideoSetPaletteColor( UCHAR Color,
|
||||
UCHAR Red, UCHAR Green, UCHAR Blue ) {
|
||||
printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue );
|
||||
}
|
||||
|
||||
VOID PpcVideoGetPaletteColor( UCHAR Color,
|
||||
UCHAR *Red, UCHAR *Green, UCHAR *Blue ) {
|
||||
printf( "GetPaletteColor(%x)\n", Color);
|
||||
}
|
||||
|
||||
VOID PpcVideoSync() {
|
||||
printf( "Sync\n" );
|
||||
}
|
||||
|
||||
int mmu_initialized = 0;
|
||||
int mem_range_end;
|
||||
VOID PpcInitializeMmu()
|
||||
{
|
||||
if(!mmu_initialized)
|
||||
{
|
||||
MmuInit();
|
||||
MmuDbgInit(0, 0x800003f8);
|
||||
MmuSetMemorySize(mem_range_end);
|
||||
//MmuDbgEnter(0x20);
|
||||
mmu_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
|
||||
ULONG MaxMemoryMapSize );
|
||||
|
||||
/*
|
||||
* Get memory the proper openfirmware way
|
||||
*/
|
||||
ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
|
||||
ULONG MaxMemoryMapSize ) {
|
||||
int i, memhandle, total = 0, slots = 0, last = 0x40000, allocstart = 0x1000000;
|
||||
int regdata[0x40];
|
||||
|
||||
printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
|
||||
|
||||
memhandle = ofw_finddevice("/memory");
|
||||
|
||||
ofw_getprop(memhandle, "reg", (char *)regdata, sizeof(regdata));
|
||||
|
||||
/* Try to claim some memory in usable blocks. Try to get some 8mb bits */
|
||||
for( i = 0; i < sizeof(claimed) / sizeof(claimed[0]); ) {
|
||||
if (!claimed[i])
|
||||
claimed[i] = ofw_claim(allocstart, 8 * 1024 * 1024, 0x1000);
|
||||
|
||||
allocstart += 8 * 1024 * 1024;
|
||||
|
||||
if (claimed[i]) {
|
||||
if (last < claimed[i]) {
|
||||
BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim;
|
||||
BiosMemoryMap[slots].BaseAddress = last;
|
||||
BiosMemoryMap[slots].Length = claimed[i] - last;
|
||||
slots++;
|
||||
}
|
||||
|
||||
BiosMemoryMap[slots].Type = BiosMemoryUsable;
|
||||
BiosMemoryMap[slots].BaseAddress = claimed[i];
|
||||
BiosMemoryMap[slots].Length = 8 * 1024 * 1024;
|
||||
|
||||
total += BiosMemoryMap[slots].Length;
|
||||
last =
|
||||
BiosMemoryMap[slots].BaseAddress +
|
||||
BiosMemoryMap[slots].Length;
|
||||
slots++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the rest until the end of the memory object as we see it */
|
||||
if (last < regdata[1]) {
|
||||
BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim;
|
||||
BiosMemoryMap[slots].BaseAddress = last;
|
||||
BiosMemoryMap[slots].Length = regdata[1] - last;
|
||||
slots++;
|
||||
}
|
||||
|
||||
for (i = 0; i < slots; i++) {
|
||||
printf("MemoryMap[%d] = (%x:%x)\n",
|
||||
i,
|
||||
(int)BiosMemoryMap[i].BaseAddress,
|
||||
(int)BiosMemoryMap[i].Length);
|
||||
|
||||
}
|
||||
|
||||
mem_range_end = regdata[1];
|
||||
|
||||
printf( "Returning memory map (%d entries, %dk free, %dk total ram)\n",
|
||||
slots, total / 1024, regdata[1] / 1024 );
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
|
||||
ULONG SectorCount, PVOID Buffer ) {
|
||||
int rlen = 0;
|
||||
|
||||
if( part_handle == -1 ) {
|
||||
part_handle = ofw_open( BootPart );
|
||||
|
||||
if( part_handle == -1 ) {
|
||||
printf("Could not open any disk devices we know about\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if( part_handle == -1 ) {
|
||||
printf("Got partition handle %x\n", part_handle);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( ofw_seek( part_handle,
|
||||
(ULONG)(SectorNumber >> 25),
|
||||
(ULONG)((SectorNumber * 512) & 0xffffffff) ) ) {
|
||||
printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) );
|
||||
return rlen > 0;
|
||||
}
|
||||
|
||||
BOOLEAN PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY DriveGeometry ) {
|
||||
printf("GetGeometry(%d)\n", DriveNumber);
|
||||
DriveGeometry->BytesPerSector = 512;
|
||||
DriveGeometry->Heads = 16;
|
||||
DriveGeometry->Sectors = 63;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
|
||||
printf("GetCacheableBlockCount\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
TIMEINFO*
|
||||
PpcGetTime(VOID)
|
||||
{
|
||||
static TIMEINFO TimeInfo;
|
||||
//printf("PpcGetTime\n");
|
||||
return &TimeInfo;
|
||||
}
|
||||
|
||||
VOID NarrowToWide(WCHAR *wide_name, char *name)
|
||||
{
|
||||
char *copy_name;
|
||||
WCHAR *wide_name_ptr;
|
||||
for (wide_name_ptr = wide_name, copy_name = name;
|
||||
(*wide_name_ptr = *copy_name);
|
||||
wide_name_ptr++, copy_name++);
|
||||
}
|
||||
|
||||
/* Recursively copy the device tree into our representation
|
||||
* It'll be passed to HAL.
|
||||
*
|
||||
* When NT was first done on PPC, it was on PReP hardware, which is very
|
||||
* like PC hardware (really, just a PPC on a PC motherboard). HAL can guess
|
||||
* the addresses of needed resources in this scheme as it can on x86.
|
||||
*
|
||||
* Most PPC hardware doesn't assign fixed addresses to hardware, which is
|
||||
* the problem that open firmware partially solves. It allows hardware makers
|
||||
* much more leeway in building PPC systems. Unfortunately, because
|
||||
* openfirmware as originally specified neither captures nor standardizes
|
||||
* all possible information, and also because of bugs, most OSs use a hybrid
|
||||
* configuration scheme that relies both on verification of devices and
|
||||
* recording information from openfirmware to be treated as hints.
|
||||
*/
|
||||
VOID OfwCopyDeviceTree
|
||||
(PCONFIGURATION_COMPONENT_DATA ParentKey,
|
||||
char *name,
|
||||
int innode,
|
||||
ULONG *BusNumber,
|
||||
ULONG *DiskController,
|
||||
ULONG *DiskNumber)
|
||||
{
|
||||
int proplen = 0, node = innode;
|
||||
char *prev_name, cur_name[64], data[256], *slash, devtype[64];
|
||||
wchar_t wide_name[64];
|
||||
PCONFIGURATION_COMPONENT_DATA NewKey;
|
||||
|
||||
NarrowToWide(wide_name, name);
|
||||
|
||||
/* Create a key for this device */
|
||||
FldrCreateComponentKey
|
||||
(ParentKey,
|
||||
AdapterClass,
|
||||
MultiFunctionAdapter,
|
||||
0,
|
||||
0,
|
||||
(ULONG)-1,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&NewKey);
|
||||
|
||||
/* Add properties */
|
||||
for (prev_name = ""; ofw_nextprop(node, prev_name, cur_name) == 1; )
|
||||
{
|
||||
proplen = ofw_getproplen(node, cur_name);
|
||||
if (proplen > 256 || proplen < 0)
|
||||
{
|
||||
printf("Warning: not getting prop %s (too long: %d)\n",
|
||||
cur_name, proplen);
|
||||
continue;
|
||||
}
|
||||
ofw_getprop(node, cur_name, data, sizeof(data));
|
||||
|
||||
/* Get device type so we can examine it */
|
||||
if (!strcmp(cur_name, "device_type"))
|
||||
strcpy(devtype, (char *)data);
|
||||
|
||||
NarrowToWide(wide_name, cur_name);
|
||||
//RegSetValue(NewKey, wide_name, REG_BINARY, data, proplen);
|
||||
|
||||
strcpy(data, cur_name);
|
||||
prev_name = data;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Special device handling */
|
||||
if (!strcmp(devtype, "ata"))
|
||||
{
|
||||
OfwHandleDiskController(NewKey, node, *DiskController);
|
||||
(*DiskController)++;
|
||||
*DiskNumber = 0;
|
||||
}
|
||||
else if (!strcmp(devtype, "disk"))
|
||||
{
|
||||
OfwHandleDiskObject(NewKey, node, *DiskController, *DiskNumber);
|
||||
(*DiskNumber)++;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Subdevices */
|
||||
for (node = ofw_child(node); node; node = ofw_peer(node))
|
||||
{
|
||||
ofw_package_to_path(node, data, sizeof(data));
|
||||
slash = strrchr(data, '/');
|
||||
if (slash) slash++; else continue;
|
||||
OfwCopyDeviceTree
|
||||
(NewKey, slash, node, BusNumber, DiskController, DiskNumber);
|
||||
}
|
||||
}
|
||||
|
||||
PCONFIGURATION_COMPONENT_DATA PpcHwDetect() {
|
||||
PCONFIGURATION_COMPONENT_DATA RootKey;
|
||||
ULONG BusNumber = 0, DiskController = 0, DiskNumber = 0;
|
||||
int node = ofw_finddevice("/");
|
||||
|
||||
FldrCreateSystemKey(&RootKey);
|
||||
|
||||
OfwCopyDeviceTree(RootKey,"/",node,&BusNumber,&DiskController,&DiskNumber);
|
||||
return RootKey;
|
||||
}
|
||||
|
||||
VOID
|
||||
PpcHwIdle(VOID)
|
||||
{
|
||||
/* UNIMPLEMENTED */
|
||||
}
|
||||
|
||||
void PpcDefaultMachVtbl()
|
||||
{
|
||||
MachVtbl.ConsPutChar = PpcOfwPutChar;
|
||||
MachVtbl.ConsKbHit = PpcConsKbHit;
|
||||
MachVtbl.ConsGetCh = PpcConsGetCh;
|
||||
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
|
||||
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
|
||||
MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize;
|
||||
MachVtbl.VideoGetBufferSize = PpcVideoGetBufferSize;
|
||||
MachVtbl.VideoSetTextCursorPosition = PpcVideoSetTextCursorPosition;
|
||||
MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor;
|
||||
MachVtbl.VideoPutChar = PpcVideoPutChar;
|
||||
MachVtbl.VideoCopyOffScreenBufferToVRAM =
|
||||
PpcVideoCopyOffScreenBufferToVRAM;
|
||||
MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed;
|
||||
MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor;
|
||||
MachVtbl.VideoGetPaletteColor = PpcVideoGetPaletteColor;
|
||||
MachVtbl.VideoSync = PpcVideoSync;
|
||||
|
||||
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
|
||||
|
||||
MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors;
|
||||
MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry;
|
||||
MachVtbl.DiskGetCacheableBlockCount = PpcDiskGetCacheableBlockCount;
|
||||
|
||||
MachVtbl.GetTime = PpcGetTime;
|
||||
|
||||
MachVtbl.HwDetect = PpcHwDetect;
|
||||
MachVtbl.HwIdle = PpcHwIdle;
|
||||
}
|
||||
|
||||
void PpcOfwInit()
|
||||
{
|
||||
chosen_package = ofw_finddevice( "/chosen" );
|
||||
|
||||
ofw_getprop(chosen_package, "bootargs",
|
||||
CmdLine, sizeof(CmdLine));
|
||||
ofw_getprop( chosen_package, "stdin",
|
||||
(char *)&stdin_handle, sizeof(stdin_handle) );
|
||||
ofw_getprop( chosen_package, "stdout",
|
||||
(char *)&stdout_handle, sizeof(stdout_handle) );
|
||||
ofw_getprop( chosen_package, "mmu",
|
||||
(char *)&mmu_handle, sizeof(mmu_handle) );
|
||||
|
||||
// Allow forcing prep for broken OFW
|
||||
if(!strncmp(CmdLine, "bootprep", 8))
|
||||
{
|
||||
printf("Going to PREP init...\n");
|
||||
ofproxy = NULL;
|
||||
PpcPrepInit();
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "FreeLDR version [%s]\n", FrLdrVersionString );
|
||||
|
||||
BootMain( CmdLine );
|
||||
}
|
||||
|
||||
void PpcInit( of_proxy the_ofproxy ) {
|
||||
// Hack to be a bit easier on ram
|
||||
CacheSizeLimit = 64 * 1024;
|
||||
ofproxy = the_ofproxy;
|
||||
PpcDefaultMachVtbl();
|
||||
if(ofproxy) PpcOfwInit();
|
||||
else PpcPrepInit();
|
||||
}
|
||||
|
||||
void MachInit(const char *CmdLine) {
|
||||
int i, len;
|
||||
char *sep;
|
||||
|
||||
BootPart[0] = 0;
|
||||
FrLdrBootPath[0] = 0;
|
||||
|
||||
printf( "Determining boot device: [%s]\n", CmdLine );
|
||||
|
||||
sep = NULL;
|
||||
for( i = 0; i < strlen(CmdLine); i++ ) {
|
||||
if( strncmp(CmdLine + i, "boot=", 5) == 0) {
|
||||
strcpy(BootPart, CmdLine + i + 5);
|
||||
sep = strchr(BootPart, ',');
|
||||
if( sep )
|
||||
*sep = 0;
|
||||
while(CmdLine[i] && CmdLine[i]!=',') i++;
|
||||
}
|
||||
}
|
||||
|
||||
if( strlen(BootPart) == 0 ) {
|
||||
if (ofproxy)
|
||||
len = ofw_getprop(chosen_package, "bootpath",
|
||||
FrLdrBootPath, sizeof(FrLdrBootPath));
|
||||
else
|
||||
len = 0;
|
||||
if( len < 0 ) len = 0;
|
||||
FrLdrBootPath[len] = 0;
|
||||
printf( "Boot Path: %s\n", FrLdrBootPath );
|
||||
|
||||
sep = strrchr(FrLdrBootPath, ',');
|
||||
|
||||
strcpy(BootPart, FrLdrBootPath);
|
||||
if( sep ) {
|
||||
BootPart[sep - FrLdrBootPath] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "FreeLDR starting (boot partition: %s)\n", BootPart );
|
||||
}
|
||||
|
||||
void beep() {
|
||||
}
|
||||
|
||||
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address) {
|
||||
return GetPhysByte(((ULONG)Address)+0x80000000);
|
||||
}
|
||||
|
||||
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
|
||||
SetPhysByte(((ULONG)Address)+0x80000000, Value);
|
||||
}
|
||||
|
||||
VOID __cdecl BootLinuxKernel(
|
||||
IN ULONG KernelSize,
|
||||
IN PVOID KernelCurrentLoadAddress,
|
||||
IN PVOID KernelTargetLoadAddress,
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber)
|
||||
{
|
||||
ofw_exit();
|
||||
}
|
||||
|
||||
VOID __cdecl ChainLoadBiosBootSectorCode(
|
||||
IN UCHAR BootDrive OPTIONAL,
|
||||
IN ULONG BootPartition OPTIONAL)
|
||||
{
|
||||
ofw_exit();
|
||||
}
|
||||
|
||||
void DbgBreakPoint() {
|
||||
__asm__("twi 31,0,0");
|
||||
}
|
@ -1,852 +0,0 @@
|
||||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <elf/elf.h>
|
||||
#include <elf/reactos.h>
|
||||
#include <of.h>
|
||||
#include "ppcmmu/mmu.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
/* We'll check this to see if we're in OFW land */
|
||||
extern of_proxy ofproxy;
|
||||
|
||||
PVOID KernelMemory = NULL;
|
||||
|
||||
/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
|
||||
#define PFN_SHIFT 12
|
||||
|
||||
/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */
|
||||
#define PDE_SHIFT 22
|
||||
#define PDE_SHIFT_PAE 18
|
||||
|
||||
#define STARTUP_BASE 0xC0000000
|
||||
#define HYPERSPACE_BASE 0xC0400000
|
||||
#define HYPERSPACE_PAE_BASE 0xC0800000
|
||||
#define APIC_BASE 0xFEC00000
|
||||
#define KPCR_BASE 0xFF000000
|
||||
|
||||
#define LowMemPageTableIndex 0
|
||||
#define StartupPageTableIndex (STARTUP_BASE >> 22)
|
||||
#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22)
|
||||
#define KpcrPageTableIndex (KPCR_BASE >> 22)
|
||||
#define ApicPageTableIndex (APIC_BASE >> 22)
|
||||
|
||||
#define BAT_GRANULARITY (64 * 1024)
|
||||
#define KernelMemorySize (8 * 1024 * 1024)
|
||||
#define XROUNDUP(x,n) ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
|
||||
|
||||
#define TAG_MBOOT 'oobM'
|
||||
|
||||
char reactos_module_strings[64][256]; // Array to hold module names
|
||||
|
||||
/* Load Address of Next Module */
|
||||
ULONG_PTR NextModuleBase = 0;
|
||||
|
||||
/* Currently Opened Module */
|
||||
PLOADER_MODULE CurrentModule = NULL;
|
||||
|
||||
/* Unrelocated Kernel Base in Virtual Memory */
|
||||
ULONG_PTR KernelBase;
|
||||
|
||||
/* Wether PAE is to be used or not */
|
||||
BOOLEAN PaeModeEnabled;
|
||||
|
||||
/* Kernel Entrypoint in Physical Memory */
|
||||
ULONG_PTR KernelEntryPoint;
|
||||
|
||||
/* Dummy to bring in memmove */
|
||||
PVOID memmove_dummy = memmove;
|
||||
|
||||
PLOADER_MODULE
|
||||
NTAPI
|
||||
LdrGetModuleObject(PCHAR ModuleName);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrPEFixupImports(IN PVOID DllBase,
|
||||
IN PCHAR DllName);
|
||||
|
||||
VOID PpcInitializeMmu(int max);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*++
|
||||
* FrLdrStartup
|
||||
* INTERNAL
|
||||
*
|
||||
* Prepares the system for loading the Kernel.
|
||||
*
|
||||
* Params:
|
||||
* Magic - Multiboot Magic
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
|
||||
typedef void (*KernelEntryFn)( void * );
|
||||
|
||||
int MmuPageMiss(int trapCode, ppc_trap_frame_t *trap)
|
||||
{
|
||||
int i;
|
||||
printf("TRAP %x\n", trapCode);
|
||||
for( i = 0; i < 40; i++ )
|
||||
printf("r[%d] %x\n", i, trap->gpr[i]);
|
||||
printf("HALT!\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
typedef struct _ppc_map_set_t {
|
||||
int mapsize;
|
||||
int usecount;
|
||||
ppc_map_info_t *info;
|
||||
} ppc_map_set_t;
|
||||
|
||||
extern int mmu_handle;
|
||||
paddr_t MmuTranslate(paddr_t possibly_virtual)
|
||||
{
|
||||
if (ofproxy)
|
||||
{
|
||||
/* Openfirmware takes liberties with boot-time memory.
|
||||
* if you're in a unitary kernel, it's not as difficult, but since
|
||||
* we rely on loading things into virtual space from here, we need
|
||||
* to detect the mappings so far.
|
||||
*/
|
||||
int args[2];
|
||||
args[0] = possibly_virtual;
|
||||
args[1] = 1; /* Marker to tell we want a physical addr */
|
||||
return (paddr_t)ofw_callmethod_ret("translate", mmu_handle, 2, args, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other booters don't remap ram */
|
||||
return possibly_virtual;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FrLdrAddPageMapping(ppc_map_set_t *set, int proc, paddr_t phys, vaddr_t virt)
|
||||
{
|
||||
int j;
|
||||
paddr_t page = ROUND_DOWN(phys, (1<<PFN_SHIFT));
|
||||
|
||||
if (virt == 0)
|
||||
virt = ROUND_DOWN(page, (1<<PFN_SHIFT));
|
||||
else
|
||||
virt = ROUND_DOWN(virt, (1<<PFN_SHIFT));
|
||||
|
||||
page = MmuTranslate(page);
|
||||
|
||||
//printf("Mapping virt [%x] to phys [%x (from) %x]\n", virt, page, phys);
|
||||
|
||||
for( j = 0; j < set->usecount; j++ )
|
||||
{
|
||||
if(set->info[j].addr == page) return;
|
||||
}
|
||||
|
||||
if (!set->mapsize)
|
||||
{
|
||||
set->mapsize = 0x80;
|
||||
set->info = MmAllocateMemory(0x80 * sizeof(*set->info));
|
||||
}
|
||||
else if (set->mapsize <= set->usecount)
|
||||
{
|
||||
ppc_map_info_t *newinfo = MmAllocateMemory(set->mapsize * 2 * sizeof(*set->info));
|
||||
memcpy(newinfo, set->info, set->mapsize * sizeof(*set->info));
|
||||
MmFreeMemory(set->info);
|
||||
set->info = newinfo;
|
||||
set->mapsize *= 2;
|
||||
}
|
||||
|
||||
set->info[set->usecount].flags = MMU_ALL_RW;
|
||||
set->info[set->usecount].proc = proc;
|
||||
set->info[set->usecount].addr = virt;
|
||||
set->info[set->usecount].phys = page;
|
||||
set->usecount++;
|
||||
}
|
||||
|
||||
extern int _start[], _end[];
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FrLdrStartup(ULONG Magic)
|
||||
{
|
||||
ULONG_PTR i, tmp, OldModCount = 0;
|
||||
PCHAR ModHeader;
|
||||
CHAR ModulesTreated[64] = { 0 };
|
||||
ULONG NumberOfEntries = 0, UsedEntries = 0;
|
||||
PPAGE_LOOKUP_TABLE_ITEM FreeLdrMap = MmGetMemoryMap(&NumberOfEntries);
|
||||
ppc_map_set_t memmap = { };
|
||||
|
||||
printf("FrLdrStartup\n");
|
||||
|
||||
/* Disable EE */
|
||||
__asm__("mfmsr %0" : "=r" (tmp));
|
||||
tmp &= 0x7fff;
|
||||
__asm__("mtmsr %0" : : "r" (tmp));
|
||||
|
||||
while(OldModCount != LoaderBlock.ModsCount)
|
||||
{
|
||||
printf("Added %d modules last pass\n",
|
||||
LoaderBlock.ModsCount - OldModCount);
|
||||
|
||||
OldModCount = LoaderBlock.ModsCount;
|
||||
|
||||
for(i = 0; i < LoaderBlock.ModsCount; i++)
|
||||
{
|
||||
if (!ModulesTreated[i])
|
||||
{
|
||||
ModulesTreated[i] = 1;
|
||||
ModHeader = ((PCHAR)reactos_modules[i].ModStart);
|
||||
if(ModHeader[0] == 'M' && ModHeader[1] == 'Z')
|
||||
LdrPEFixupImports
|
||||
((PVOID)reactos_modules[i].ModStart,
|
||||
(PCHAR)reactos_modules[i].String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Starting mmu\n");
|
||||
|
||||
PpcInitializeMmu(0);
|
||||
|
||||
printf("Allocating vsid 0 (kernel)\n");
|
||||
MmuAllocVsid(0, 0xff00);
|
||||
|
||||
/* We'll use vsid 1 for freeldr (expendable) */
|
||||
printf("Allocating vsid 1 (freeldr)\n");
|
||||
MmuAllocVsid(1, 0xff);
|
||||
|
||||
printf("Mapping Freeldr Code (%x-%x)\n", _start, _end);
|
||||
|
||||
/* Map memory zones */
|
||||
/* Freeldr itself */
|
||||
for( i = (int)_start;
|
||||
i < (int)_end;
|
||||
i += (1<<PFN_SHIFT) ) {
|
||||
FrLdrAddPageMapping(&memmap, 1, i, 0);
|
||||
}
|
||||
|
||||
printf("KernelBase %x\n", KernelBase);
|
||||
|
||||
/* Heap pages -- this gets the entire freeldr heap */
|
||||
for( i = 0; i < NumberOfEntries; i++ ) {
|
||||
tmp = i<<PFN_SHIFT;
|
||||
if (FreeLdrMap[i].PageAllocated == LoaderSystemCode) {
|
||||
UsedEntries++;
|
||||
if (tmp >= (ULONG)KernelMemory &&
|
||||
tmp < (ULONG)KernelMemory + KernelMemorySize) {
|
||||
FrLdrAddPageMapping(&memmap, 0, tmp, KernelBase + tmp - (ULONG)KernelMemory);
|
||||
} else {
|
||||
FrLdrAddPageMapping(&memmap, 1, tmp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MmuMapPage(memmap.info, memmap.usecount);
|
||||
|
||||
printf("Finished Mapping the Freeldr Heap (used %d pages)\n", UsedEntries);
|
||||
|
||||
printf("Setting initial segments\n");
|
||||
MmuSetVsid(0, 8, 1);
|
||||
MmuSetVsid(8, 16, 0);
|
||||
|
||||
printf("Segments set!\n");
|
||||
|
||||
MmuTurnOn((KernelEntryFn)KernelEntryPoint, &LoaderBlock);
|
||||
|
||||
/* Nothing more */
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrSetupPae
|
||||
* INTERNAL
|
||||
*
|
||||
* Configures PAE on a MP System, and sets the PDBR if it's supported, or if
|
||||
* the system is UP.
|
||||
*
|
||||
* Params:
|
||||
* Magic - Multiboot Magic
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrSetupPae(ULONG Magic)
|
||||
{
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrGetKernelBase
|
||||
* INTERNAL
|
||||
*
|
||||
* Gets the Kernel Base to use.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* Sets both the FreeLdr internal variable as well as the one which
|
||||
* will be used by the Kernel.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrGetKernelBase(VOID)
|
||||
{
|
||||
PCHAR p;
|
||||
|
||||
/* Default kernel base at 2GB */
|
||||
KernelBase = 0x80800000;
|
||||
|
||||
/* Set KernelBase */
|
||||
LoaderBlock.KernelBase = 0x80000000;
|
||||
|
||||
/* Read Command Line */
|
||||
p = (PCHAR)LoaderBlock.CommandLine;
|
||||
while ((p = strchr(p, '/')) != NULL) {
|
||||
|
||||
/* Find "/3GB" */
|
||||
if (!_strnicmp(p + 1, "3GB", 3)) {
|
||||
|
||||
/* Make sure there's nothing following it */
|
||||
if (p[4] == ' ' || p[4] == 0) {
|
||||
|
||||
/* Use 3GB */
|
||||
KernelBase = 0xE0000000;
|
||||
LoaderBlock.KernelBase = 0xC0000000;
|
||||
}
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrGetPaeMode
|
||||
* INTERNAL
|
||||
*
|
||||
* Determines whether PAE mode should be enabled or not.
|
||||
*
|
||||
* Params:
|
||||
* None.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrGetPaeMode(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrSetupPageDirectory
|
||||
* INTERNAL
|
||||
*
|
||||
* Sets up the ReactOS Startup Page Directory.
|
||||
*
|
||||
* Params:
|
||||
* None.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* We are setting PDEs, but using the equivalent (for our purpose) PTE structure.
|
||||
* As such, please note that PageFrameNumber == PageEntryNumber.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrSetupPageDirectory(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrMapModule
|
||||
* INTERNAL
|
||||
*
|
||||
* Loads the indicated elf image as PE. The target will appear to be
|
||||
* a PE image whose ImageBase has ever been KernelAddr.
|
||||
*
|
||||
* Params:
|
||||
* Image -- File to load
|
||||
* ImageName -- Name of image for the modules list
|
||||
* MemLoadAddr -- Freeldr address of module
|
||||
* KernelAddr -- Kernel address of module
|
||||
*--*/
|
||||
#define ELF_SECTION(n) ((Elf32_Shdr*)(sptr + (n * shsize)))
|
||||
#define COFF_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+(SWAPW(((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))))
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG KernelAddr)
|
||||
{
|
||||
PIMAGE_DOS_HEADER ImageHeader = 0;
|
||||
PIMAGE_NT_HEADERS NtHeader = 0;
|
||||
PIMAGE_SECTION_HEADER Section;
|
||||
ULONG SectionCount;
|
||||
ULONG ImageSize;
|
||||
INT i, j;
|
||||
PLOADER_MODULE ModuleData;
|
||||
//int phsize, phnum;
|
||||
int shsize, shnum, relsize, SectionAddr = 0;
|
||||
PCHAR sptr;
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Shdr *shdr;
|
||||
LARGE_INTEGER Position;
|
||||
PSTR TempName;
|
||||
|
||||
TempName = strrchr(ImageName, '\\');
|
||||
if(TempName) TempName++; else TempName = (PSTR)ImageName;
|
||||
ModuleData = LdrGetModuleObject(TempName);
|
||||
|
||||
if(ModuleData)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(!KernelAddr)
|
||||
KernelAddr = (ULONG)NextModuleBase - (ULONG)KernelMemory + KernelBase;
|
||||
if(!MemLoadAddr)
|
||||
MemLoadAddr = (PCHAR)NextModuleBase;
|
||||
|
||||
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
|
||||
//printf("Loading file (elf at %x)\n", KernelAddr);
|
||||
|
||||
/* Load the first 1024 bytes of the kernel image so we can read the PE header */
|
||||
if (ArcRead(KernelImage, &ehdr, sizeof(ehdr), NULL) != ESUCCESS) {
|
||||
|
||||
/* Fail if we couldn't read */
|
||||
printf("Couldn't read the elf header\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Start by getting elf headers */
|
||||
//phsize = ehdr.e_phentsize;
|
||||
//phnum = ehdr.e_phnum;
|
||||
shsize = ehdr.e_shentsize;
|
||||
shnum = ehdr.e_shnum;
|
||||
sptr = (PCHAR)FrLdrTempAlloc(shnum * shsize, TAG_MBOOT);
|
||||
|
||||
/* Read section headers */
|
||||
Position.QuadPart = ehdr.e_shoff;
|
||||
ArcSeek(KernelImage, &Position, SeekAbsolute);
|
||||
ArcRead(KernelImage, sptr, shsize * shnum, NULL);
|
||||
|
||||
/* Now we'll get the PE Header */
|
||||
for( i = 0; i < shnum; i++ )
|
||||
{
|
||||
shdr = ELF_SECTION(i);
|
||||
shdr->sh_addr = 0;
|
||||
|
||||
/* Find the PE Header */
|
||||
if (shdr->sh_type == TYPE_PEHEADER)
|
||||
{
|
||||
Position.QuadPart = shdr->sh_offset;
|
||||
ArcSeek(KernelImage, &Position, SeekAbsolute);
|
||||
ArcRead(KernelImage, MemLoadAddr, shdr->sh_size, NULL);
|
||||
ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
|
||||
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
|
||||
#if 0
|
||||
printf("NtHeader at %x\n", SWAPD(ImageHeader->e_lfanew));
|
||||
printf("SectionAlignment %x\n",
|
||||
SWAPD(NtHeader->OptionalHeader.SectionAlignment));
|
||||
SectionAddr = ROUND_UP
|
||||
(shdr->sh_size, SWAPD(NtHeader->OptionalHeader.SectionAlignment));
|
||||
printf("Header ends at %x\n", SectionAddr);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == shnum)
|
||||
{
|
||||
printf("No peheader section encountered :-(\n");
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
printf("DOS SIG: %s\n", (PCHAR)MemLoadAddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save the Image Base */
|
||||
NtHeader->OptionalHeader.ImageBase = SWAPD(KernelAddr);
|
||||
|
||||
/* Load the file image */
|
||||
Section = COFF_FIRST_SECTION(NtHeader);
|
||||
SectionCount = SWAPW(NtHeader->FileHeader.NumberOfSections);
|
||||
|
||||
/* Walk each section */
|
||||
for (i=0; i < SectionCount; i++, Section++)
|
||||
{
|
||||
shdr = ELF_SECTION((SWAPD(Section->PointerToRawData)+1));
|
||||
|
||||
shdr->sh_addr = SectionAddr = SWAPD(Section->VirtualAddress);
|
||||
shdr->sh_addr += KernelAddr;
|
||||
|
||||
Section->PointerToRawData = SWAPD((Section->VirtualAddress - KernelAddr));
|
||||
|
||||
if (shdr->sh_type != SHT_NOBITS)
|
||||
{
|
||||
/* Content area */
|
||||
printf("Loading section %d at %x (real: %x:%d)\n", i, KernelAddr + SectionAddr, MemLoadAddr+SectionAddr, shdr->sh_size);
|
||||
Position.QuadPart = shdr->sh_offset;
|
||||
ArcSeek(KernelImage, &Position, SeekAbsolute);
|
||||
ArcRead(KernelImage, MemLoadAddr + SectionAddr, shdr->sh_size, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Zero it out */
|
||||
printf("BSS section %d at %x\n", i, KernelAddr + SectionAddr);
|
||||
memset(MemLoadAddr + SectionAddr, 0,
|
||||
ROUND_UP(shdr->sh_size,
|
||||
SWAPD(NtHeader->OptionalHeader.SectionAlignment)));
|
||||
}
|
||||
}
|
||||
|
||||
ImageSize = SWAPD(NtHeader->OptionalHeader.SizeOfImage);
|
||||
printf("Total image size is %x\n", ImageSize);
|
||||
|
||||
/* Handle relocation sections */
|
||||
for (i = 0; i < shnum; i++) {
|
||||
Elf32_Rela reloc = { };
|
||||
ULONG *Target32;
|
||||
USHORT *Target16;
|
||||
int numreloc, relstart, targetSection;
|
||||
Elf32_Sym symbol;
|
||||
PCHAR RelocSection, SymbolSection;
|
||||
|
||||
shdr = ELF_SECTION(i);
|
||||
/* Only relocs here */
|
||||
if((shdr->sh_type != SHT_REL) &&
|
||||
(shdr->sh_type != SHT_RELA)) continue;
|
||||
|
||||
relstart = shdr->sh_offset;
|
||||
relsize = shdr->sh_type == SHT_RELA ? 12 : 8;
|
||||
numreloc = shdr->sh_size / relsize;
|
||||
targetSection = shdr->sh_info;
|
||||
|
||||
if (!ELF_SECTION(targetSection)->sh_addr) continue;
|
||||
|
||||
RelocSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
|
||||
Position.QuadPart = relstart;
|
||||
ArcSeek(KernelImage, &Position, SeekAbsolute);
|
||||
ArcRead(KernelImage, RelocSection, shdr->sh_size, NULL);
|
||||
|
||||
/* Get the symbol section */
|
||||
shdr = ELF_SECTION(shdr->sh_link);
|
||||
|
||||
SymbolSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
|
||||
Position.QuadPart = shdr->sh_offset;
|
||||
ArcSeek(KernelImage, &Position, SeekAbsolute);
|
||||
ArcRead(KernelImage, SymbolSection, shdr->sh_size, NULL);
|
||||
|
||||
for(j = 0; j < numreloc; j++)
|
||||
{
|
||||
ULONG S,A,P;
|
||||
|
||||
/* Get the reloc */
|
||||
memcpy(&reloc, RelocSection + (j * relsize), sizeof(reloc));
|
||||
|
||||
/* Get the symbol */
|
||||
memcpy(&symbol, SymbolSection + (ELF32_R_SYM(reloc.r_info) * sizeof(symbol)), sizeof(symbol));
|
||||
|
||||
/* Compute addends */
|
||||
S = symbol.st_value + ELF_SECTION(symbol.st_shndx)->sh_addr;
|
||||
A = reloc.r_addend;
|
||||
P = reloc.r_offset + ELF_SECTION(targetSection)->sh_addr;
|
||||
|
||||
#if 0
|
||||
printf("Symbol[%d] %d -> %d(%x:%x) -> %x(+%x)@%x\n",
|
||||
ELF32_R_TYPE(reloc.r_info),
|
||||
ELF32_R_SYM(reloc.r_info),
|
||||
symbol.st_shndx,
|
||||
ELF_SECTION(symbol.st_shndx)->sh_addr,
|
||||
symbol.st_value,
|
||||
S,
|
||||
A,
|
||||
P);
|
||||
#endif
|
||||
|
||||
Target32 = (ULONG*)(((PCHAR)MemLoadAddr) + (P - KernelAddr));
|
||||
Target16 = (USHORT *)Target32;
|
||||
|
||||
switch (ELF32_R_TYPE(reloc.r_info))
|
||||
{
|
||||
case R_PPC_NONE:
|
||||
break;
|
||||
case R_PPC_ADDR32:
|
||||
*Target32 = S + A;
|
||||
break;
|
||||
case R_PPC_REL32:
|
||||
*Target32 = S + A - P;
|
||||
break;
|
||||
case R_PPC_UADDR32: /* Special: Treat as RVA */
|
||||
*Target32 = S + A - KernelAddr;
|
||||
break;
|
||||
case R_PPC_ADDR24:
|
||||
*Target32 = (ADDR24_MASK & (S+A)) | (*Target32 & ~ADDR24_MASK);
|
||||
break;
|
||||
case R_PPC_REL24:
|
||||
*Target32 = (ADDR24_MASK & (S+A-P)) | (*Target32 & ~ADDR24_MASK);
|
||||
break;
|
||||
case R_PPC_ADDR16_LO:
|
||||
*Target16 = S + A;
|
||||
break;
|
||||
case R_PPC_ADDR16_HA:
|
||||
*Target16 = (S + A + 0x8000) >> 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("reloc[%d:%x]: (type %x sym %d val %d) off %x add %x (old %x new %x)\n",
|
||||
j,
|
||||
((ULONG)Target32) - ((ULONG)MemLoadAddr),
|
||||
ELF32_R_TYPE(reloc.r_info),
|
||||
ELF32_R_SYM(reloc.r_info),
|
||||
symbol.st_value,
|
||||
reloc.r_offset, reloc.r_addend,
|
||||
x, *Target32);
|
||||
#endif
|
||||
}
|
||||
|
||||
FrLdrTempFree(SymbolSection, TAG_MBOOT);
|
||||
FrLdrTempFree(RelocSection, TAG_MBOOT);
|
||||
}
|
||||
|
||||
FrLdrTempFree(sptr, TAG_MBOOT);
|
||||
|
||||
ModuleData->ModStart = (ULONG)MemLoadAddr;
|
||||
/* Increase the next Load Base */
|
||||
NextModuleBase = ROUND_UP((ULONG)MemLoadAddr + ImageSize, PAGE_SIZE);
|
||||
ModuleData->ModEnd = NextModuleBase;
|
||||
ModuleData->String = (ULONG)MmAllocateMemory(strlen(ImageName)+1);
|
||||
strcpy((PCHAR)ModuleData->String, ImageName);
|
||||
printf("Module %s (%x-%x) next at %x\n",
|
||||
ModuleData->String,
|
||||
ModuleData->ModStart,
|
||||
ModuleData->ModEnd,
|
||||
NextModuleBase);
|
||||
LoaderBlock.ModsCount++;
|
||||
|
||||
/* Return Success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrMapKernel
|
||||
* INTERNAL
|
||||
*
|
||||
* Maps the Kernel into memory, does PE Section Mapping, initializes the
|
||||
* uninitialized data sections, and relocates the image.
|
||||
*
|
||||
* Params:
|
||||
* KernelImage - FILE Structure representing the ntoskrnl image file.
|
||||
*
|
||||
* Returns:
|
||||
* TRUE if the Kernel was mapped.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FrLdrMapKernel(FILE *KernelImage)
|
||||
{
|
||||
/* Get Kernel Base */
|
||||
FrLdrGetKernelBase();
|
||||
|
||||
/* Allocate kernel memory */
|
||||
KernelMemory = MmAllocateMemory(KernelMemorySize);
|
||||
|
||||
return FrLdrMapModule(KernelImage, "ntoskrnl.exe", KernelMemory, KernelBase);
|
||||
}
|
||||
|
||||
ULONG_PTR
|
||||
NTAPI
|
||||
FrLdrLoadModule(FILE *ModuleImage,
|
||||
PCSTR ModuleName,
|
||||
PULONG ModuleSize)
|
||||
{
|
||||
ARC_STATUS Status;
|
||||
FILEINFORMATION FileInfo;
|
||||
ULONG LocalModuleSize;
|
||||
ULONG_PTR ThisModuleBase = NextModuleBase;
|
||||
PLOADER_MODULE ModuleData;
|
||||
PSTR NameBuffer;
|
||||
PSTR TempName;
|
||||
|
||||
/* Get current module data structure and module name string array */
|
||||
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
|
||||
|
||||
/* Get only the Module Name */
|
||||
do {
|
||||
|
||||
TempName = strchr(ModuleName, '\\');
|
||||
|
||||
if(TempName) {
|
||||
ModuleName = TempName + 1;
|
||||
}
|
||||
|
||||
} while(TempName);
|
||||
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
|
||||
|
||||
/* Get Module Size */
|
||||
Status = ArcGetFileInformation(ModuleImage, &FileInfo);
|
||||
if (Status != ESUCCESS || FileInfo.EndingAddress.HighPart != 0)
|
||||
LocalModuleSize = 0;
|
||||
else
|
||||
LocalModuleSize = FileInfo.EndingAddress.LowPart;
|
||||
|
||||
/* Fill out Module Data Structure */
|
||||
ModuleData->ModStart = NextModuleBase;
|
||||
ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
|
||||
|
||||
/* Save name */
|
||||
strcpy(NameBuffer, ModuleName);
|
||||
ModuleData->String = (ULONG_PTR)NameBuffer;
|
||||
|
||||
/* Load the file image */
|
||||
ArcRead(ModuleImage, (PVOID)NextModuleBase, LocalModuleSize, NULL);
|
||||
|
||||
/* Move to next memory block and increase Module Count */
|
||||
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
|
||||
LoaderBlock.ModsCount++;
|
||||
|
||||
/* Return Module Size if required */
|
||||
if (ModuleSize != NULL) {
|
||||
*ModuleSize = LocalModuleSize;
|
||||
}
|
||||
|
||||
printf("Module %s (%x-%x) next at %x\n",
|
||||
ModuleData->String,
|
||||
ModuleData->ModStart,
|
||||
ModuleData->ModEnd,
|
||||
NextModuleBase);
|
||||
|
||||
return ThisModuleBase;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
FrLdrMapImage(IN FILE *Image, IN PCHAR ShortName, IN ULONG ImageType)
|
||||
{
|
||||
PVOID Result = NULL;
|
||||
|
||||
printf("Loading image %s (type %d)\n", ShortName, ImageType);
|
||||
|
||||
if (ImageType == 1)
|
||||
{
|
||||
if(FrLdrMapKernel(Image))
|
||||
Result = (PVOID)KernelMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
PVOID ModuleBase = (PVOID)NextModuleBase;
|
||||
|
||||
if(FrLdrMapModule(Image, ShortName, 0, 0))
|
||||
Result = ModuleBase;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
ULONG_PTR
|
||||
NTAPI
|
||||
FrLdrCreateModule(PCSTR ModuleName)
|
||||
{
|
||||
PLOADER_MODULE ModuleData;
|
||||
PSTR NameBuffer;
|
||||
|
||||
/* Get current module data structure and module name string array */
|
||||
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
|
||||
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
|
||||
|
||||
/* Set up the structure */
|
||||
ModuleData->ModStart = NextModuleBase;
|
||||
ModuleData->ModEnd = -1;
|
||||
|
||||
/* Copy the name */
|
||||
strcpy(NameBuffer, ModuleName);
|
||||
ModuleData->String = (ULONG_PTR)NameBuffer;
|
||||
|
||||
/* Set the current Module */
|
||||
CurrentModule = ModuleData;
|
||||
|
||||
/* Return Module Base Address */
|
||||
return(ModuleData->ModStart);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FrLdrCloseModule(ULONG_PTR ModuleBase,
|
||||
ULONG ModuleSize)
|
||||
{
|
||||
PLOADER_MODULE ModuleData = CurrentModule;
|
||||
|
||||
/* Make sure a module is opened */
|
||||
if (ModuleData) {
|
||||
|
||||
/* Make sure this is the right module and that it hasn't been closed */
|
||||
if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == MAXULONG_PTR)) {
|
||||
|
||||
/* Close the Module */
|
||||
ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
|
||||
|
||||
/* Set the next Module Base and increase the number of modules */
|
||||
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
|
||||
LoaderBlock.ModsCount++;
|
||||
|
||||
/* Close the currently opened module */
|
||||
CurrentModule = NULL;
|
||||
|
||||
/* Success */
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Failure path */
|
||||
return(FALSE);
|
||||
}
|
@ -1,399 +0,0 @@
|
||||
#include <freeldr.h>
|
||||
#include "ppcmmu/mmu.h"
|
||||
|
||||
inline int GetMSR() {
|
||||
register int res asm ("r3");
|
||||
__asm__("mfmsr 3");
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int GetDEC() {
|
||||
register int res asm ("r3");
|
||||
__asm__("mfdec 3");
|
||||
return res;
|
||||
}
|
||||
|
||||
__asm__("\t.globl GetPhys\n"
|
||||
"GetPhys:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl GetPhysHalf\n"
|
||||
"GetPhysHalf:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl GetPhysByte\n"
|
||||
"GetPhysByte:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhys\n"
|
||||
"SetPhys:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhysHalf\n"
|
||||
"SetPhysHalf:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhysByte\n"
|
||||
"SetPhysByte:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
inline int GetSR(int n) {
|
||||
register int res asm ("r3");
|
||||
switch( n ) {
|
||||
case 0:
|
||||
__asm__("mfsr 3,0");
|
||||
break;
|
||||
case 1:
|
||||
__asm__("mfsr 3,1");
|
||||
break;
|
||||
case 2:
|
||||
__asm__("mfsr 3,2");
|
||||
break;
|
||||
case 3:
|
||||
__asm__("mfsr 3,3");
|
||||
break;
|
||||
case 4:
|
||||
__asm__("mfsr 3,4");
|
||||
break;
|
||||
case 5:
|
||||
__asm__("mfsr 3,5");
|
||||
break;
|
||||
case 6:
|
||||
__asm__("mfsr 3,6");
|
||||
break;
|
||||
case 7:
|
||||
__asm__("mfsr 3,7");
|
||||
break;
|
||||
case 8:
|
||||
__asm__("mfsr 3,8");
|
||||
break;
|
||||
case 9:
|
||||
__asm__("mfsr 3,9");
|
||||
break;
|
||||
case 10:
|
||||
__asm__("mfsr 3,10");
|
||||
break;
|
||||
case 11:
|
||||
__asm__("mfsr 3,11");
|
||||
break;
|
||||
case 12:
|
||||
__asm__("mfsr 3,12");
|
||||
break;
|
||||
case 13:
|
||||
__asm__("mfsr 3,13");
|
||||
break;
|
||||
case 14:
|
||||
__asm__("mfsr 3,14");
|
||||
break;
|
||||
case 15:
|
||||
__asm__("mfsr 3,15");
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void GetBat( int bat, int inst, int *batHi, int *batLo ) {
|
||||
register int bh asm("r3"), bl asm("r4");
|
||||
if( inst ) {
|
||||
switch( bat ) {
|
||||
case 0:
|
||||
__asm__("mfibatu 3,0");
|
||||
__asm__("mfibatl 4,0");
|
||||
break;
|
||||
case 1:
|
||||
__asm__("mfibatu 3,1");
|
||||
__asm__("mfibatl 4,1");
|
||||
break;
|
||||
case 2:
|
||||
__asm__("mfibatu 3,2");
|
||||
__asm__("mfibatl 4,2");
|
||||
break;
|
||||
case 3:
|
||||
__asm__("mfibatu 3,3");
|
||||
__asm__("mfibatl 4,3");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch( bat ) {
|
||||
case 0:
|
||||
__asm__("mfdbatu 3,0");
|
||||
__asm__("mfdbatl 4,0");
|
||||
break;
|
||||
case 1:
|
||||
__asm__("mfdbatu 3,1");
|
||||
__asm__("mfdbatl 4,1");
|
||||
break;
|
||||
case 2:
|
||||
__asm__("mfdbatu 3,2");
|
||||
__asm__("mfdbatl 4,2");
|
||||
break;
|
||||
case 3:
|
||||
__asm__("mfdbatu 3,3");
|
||||
__asm__("mfdbatl 4,3");
|
||||
break;
|
||||
}
|
||||
}
|
||||
*batHi = bh;
|
||||
*batLo = bl;
|
||||
}
|
||||
|
||||
inline void SetBat( int bat, int inst, int batHi, int batLo ) {
|
||||
register int bh asm("r3"), bl asm("r4");
|
||||
bh = batHi;
|
||||
bl = batLo;
|
||||
if( inst ) {
|
||||
switch( bat ) {
|
||||
case 0:
|
||||
__asm__("mtibatu 0,3");
|
||||
__asm__("mtibatl 0,4");
|
||||
break;
|
||||
case 1:
|
||||
__asm__("mtibatu 1,3");
|
||||
__asm__("mtibatl 1,4");
|
||||
break;
|
||||
case 2:
|
||||
__asm__("mtibatu 2,3");
|
||||
__asm__("mtibatl 2,4");
|
||||
break;
|
||||
case 3:
|
||||
__asm__("mtibatu 3,3");
|
||||
__asm__("mtibatl 3,4");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch( bat ) {
|
||||
case 0:
|
||||
__asm__("mtdbatu 0,3");
|
||||
__asm__("mtdbatl 0,4");
|
||||
break;
|
||||
case 1:
|
||||
__asm__("mtdbatu 1,3");
|
||||
__asm__("mtdbatl 1,4");
|
||||
break;
|
||||
case 2:
|
||||
__asm__("mtdbatu 2,3");
|
||||
__asm__("mtdbatl 2,4");
|
||||
break;
|
||||
case 3:
|
||||
__asm__("mtdbatu 3,3");
|
||||
__asm__("mtdbatl 3,4");
|
||||
break;
|
||||
}
|
||||
}
|
||||
__asm__("isync\n\tsync");
|
||||
}
|
||||
|
||||
inline int GetSDR1() {
|
||||
register int res asm("r3");
|
||||
__asm__("mfsdr1 3");
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void SetSDR1( int sdr ) {
|
||||
#if 0
|
||||
int i,j;
|
||||
#endif
|
||||
__asm__("mtsdr1 3");
|
||||
#if 0
|
||||
__asm__("sync");
|
||||
__asm__("isync");
|
||||
__asm__("ptesync");
|
||||
|
||||
for( i = 0; i < 256; i++ ) {
|
||||
j = i << 12;
|
||||
__asm__("tlbie %0,0" : : "r" (j));
|
||||
}
|
||||
__asm__("eieio");
|
||||
__asm__("tlbsync");
|
||||
__asm__("ptesync");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int BatHit( int bath, int batl, int virt ) {
|
||||
int mask = 0xfffe0000 & ~((batl & 0x3f) << 17);
|
||||
return (batl & 0x40) && ((virt & mask) == (bath & mask));
|
||||
}
|
||||
|
||||
inline int BatTranslate( int bath, int batl, int virt ) {
|
||||
return (virt & 0x007fffff) | (batl & 0xfffe0000);
|
||||
}
|
||||
|
||||
/* translate address */
|
||||
int PpcVirt2phys( int virt, int inst ) {
|
||||
int msr = GetMSR();
|
||||
int txmask = inst ? 0x20 : 0x10;
|
||||
int i, bath, batl, sr, sdr1, physbase, valo;
|
||||
int hash, hashmask, ptehi, ptelo, ptegaddr;
|
||||
//int vahi, npteg;
|
||||
int vsid, pteh, ptevsid, pteapi;
|
||||
|
||||
if( msr & txmask ) {
|
||||
sr = GetSR( virt >> 28 );
|
||||
vsid = sr & 0xfffffff;
|
||||
//vahi = vsid >> 4;
|
||||
valo = (vsid << 28) | (virt & 0xfffffff);
|
||||
if( sr & 0x80000000 ) {
|
||||
return valo;
|
||||
}
|
||||
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
GetBat( i, inst, &bath, &batl );
|
||||
if( BatHit( bath, batl, virt ) ) {
|
||||
return BatTranslate( bath, batl, virt );
|
||||
}
|
||||
}
|
||||
|
||||
sdr1 = GetSDR1();
|
||||
|
||||
physbase = sdr1 & ~0xffff;
|
||||
hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
|
||||
hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
|
||||
//npteg = hashmask + 1;
|
||||
|
||||
for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
|
||||
ptegaddr = ((hashmask & hash) * 64) + physbase;
|
||||
|
||||
for( i = 0; i < 8; i++ ) {
|
||||
ptehi = GetPhys( ptegaddr + (i * 8) );
|
||||
ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
|
||||
|
||||
ptevsid = (ptehi >> 7) & 0xffffff;
|
||||
pteapi = ptehi & 0x3f;
|
||||
|
||||
if( (ptehi & 64) != pteh ) continue;
|
||||
if( ptevsid != (vsid & 0xffffff) ) continue;
|
||||
if( pteapi != ((virt >> 22) & 0x3f) ) continue;
|
||||
|
||||
return (ptelo & 0xfffff000) | (virt & 0xfff);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
return virt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a new page table entry for the indicated mapping */
|
||||
BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) {
|
||||
int i, ptehi, ptelo;
|
||||
int sdr1 = _sdr1 ? _sdr1 : GetSDR1();
|
||||
int sr = GetSR( (virt >> 28) & 0xf );
|
||||
int vsid = sr & 0xfffffff;
|
||||
int physbase = sdr1 & ~0xffff;
|
||||
int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
|
||||
int valo = (vsid << 28) | (virt & 0xfffffff);
|
||||
int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
|
||||
int ptegaddr = ((hashmask & hash) * 64) + physbase;
|
||||
|
||||
for( i = 0; i < 8; i++ ) {
|
||||
ptehi = GetPhys( ptegaddr + (i * 8) );
|
||||
|
||||
if( (slot != i) && (ptehi & 0x80000000) ) continue;
|
||||
|
||||
ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
|
||||
ptelo = phys & ~0xfff;
|
||||
|
||||
SetPhys( ptegaddr + (i * 8), ptehi );
|
||||
SetPhys( ptegaddr + (i * 8) + 4, ptelo );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#include <freeldr.h>
|
||||
#include "of.h"
|
||||
|
||||
typedef struct _ofw_method_call {
|
||||
const char *call_method;
|
||||
int nargs;
|
||||
int nrets;
|
||||
const char *method_name;
|
||||
int handle;
|
||||
int args_rets[8];
|
||||
} ofw_method_call;
|
||||
|
||||
extern int (*ofw_call_addr)(void *argstruct);
|
||||
|
||||
int ofw_callmethod_ret(const char *method, int handle, int nargs, int *args, int ret)
|
||||
{
|
||||
ofw_method_call callframe = { 0 };
|
||||
callframe.call_method = "call-method";
|
||||
callframe.nargs = nargs + 2;
|
||||
callframe.nrets = ret+1;
|
||||
callframe.method_name = method;
|
||||
callframe.handle = handle;
|
||||
memcpy(callframe.args_rets, args, sizeof(int)*nargs);
|
||||
ofw_call_addr(&callframe);
|
||||
return callframe.args_rets[nargs+ret];
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
.section .text
|
||||
.globl ofw_functions
|
||||
.globl ofw_call_addr
|
||||
.globl call_ofw
|
||||
call_ofw:
|
||||
/* R3 has the function offset to call (n * 4)
|
||||
* Other arg registers are unchanged. */
|
||||
subi %r1,%r1,0x100
|
||||
stw %r8,24(%r1)
|
||||
mflr %r8
|
||||
stw %r8,0(%r1)
|
||||
stw %r3,4(%r1)
|
||||
stw %r4,8(%r1)
|
||||
stw %r5,12(%r1)
|
||||
stw %r6,16(%r1)
|
||||
stw %r7,20(%r1)
|
||||
stw %r9,28(%r1)
|
||||
stw %r10,32(%r1)
|
||||
stw %r20,36(%r1)
|
||||
|
||||
lis %r10,ofw_functions@ha
|
||||
addi %r8,%r10,ofw_functions@l
|
||||
add %r8,%r3,%r8
|
||||
lwz %r9,0(%r8)
|
||||
mtctr %r9
|
||||
|
||||
mr %r3,%r4
|
||||
mr %r4,%r5
|
||||
mr %r5,%r6
|
||||
mr %r6,%r7
|
||||
mr %r7,%r8
|
||||
mr %r8,%r9
|
||||
|
||||
/* Call ofw proxy function */
|
||||
bctrl
|
||||
|
||||
lwz %r8,0(%r1)
|
||||
mtlr %r8
|
||||
lwz %r4,8(%r1)
|
||||
lwz %r5,12(%r1)
|
||||
lwz %r6,16(%r1)
|
||||
lwz %r7,20(%r1)
|
||||
lwz %r8,24(%r1)
|
||||
lwz %r9,28(%r1)
|
||||
lwz %r10,32(%r1)
|
||||
lwz %r20,36(%r1)
|
||||
addi %r1,%r1,0x100
|
||||
blr
|
@ -1,148 +0,0 @@
|
||||
#include "freeldr.h"
|
||||
#include "machine.h"
|
||||
#include "ppcmmu/mmu.h"
|
||||
#include "prep.h"
|
||||
|
||||
int prep_serial = 0x800003f8;
|
||||
extern int mem_range_end;
|
||||
|
||||
void sync() { __asm__("eieio\n\tsync"); }
|
||||
|
||||
/* Simple serial */
|
||||
|
||||
void PpcPrepPutChar( int ch ) {
|
||||
if( ch == 0x0a ) {
|
||||
SetPhysByte(prep_serial, 0x0d);
|
||||
sync();
|
||||
}
|
||||
SetPhysByte(prep_serial, ch);
|
||||
sync();
|
||||
}
|
||||
|
||||
BOOLEAN PpcPrepDiskReadLogicalSectors
|
||||
( ULONG DriveNumber, ULONGLONG SectorNumber,
|
||||
ULONG SectorCount, PVOID Buffer ) {
|
||||
int secct;
|
||||
|
||||
for(secct = 0; secct < SectorCount; secct++)
|
||||
{
|
||||
ide_seek(&ide1_desc, SectorNumber + secct, 0);
|
||||
ide_read(&ide1_desc, ((PCHAR)Buffer) + secct * 512, 512);
|
||||
}
|
||||
/* Never give up! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN PpcPrepConsKbHit()
|
||||
{
|
||||
return 1;
|
||||
//return GetPhysByte(prep_serial+5) & 1;
|
||||
}
|
||||
|
||||
int PpcPrepConsGetCh()
|
||||
{
|
||||
while(!PpcPrepConsKbHit());
|
||||
return GetPhysByte(prep_serial);
|
||||
}
|
||||
|
||||
void PpcPrepVideoClearScreen(UCHAR Attr)
|
||||
{
|
||||
printf("\033c");
|
||||
}
|
||||
|
||||
VIDEODISPLAYMODE PpcPrepVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init )
|
||||
{
|
||||
return VideoTextMode;
|
||||
}
|
||||
|
||||
void PpcPrepVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth )
|
||||
{
|
||||
*Width = 80;
|
||||
*Height = 25;
|
||||
*Depth = 16;
|
||||
}
|
||||
|
||||
VOID PpcInitializeMmu(int max);
|
||||
|
||||
ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
|
||||
ULONG MaxMemoryMapSize )
|
||||
{
|
||||
// Probe memory
|
||||
paddr_t physAddr;
|
||||
register int oldStore = 0, newStore = 0, change = 0, oldmsr;
|
||||
|
||||
__asm__("mfmsr %0\n" : "=r" (oldmsr));
|
||||
change = oldmsr & 0x6fff;
|
||||
__asm__("mtmsr %0\n" : : "r" (change));
|
||||
|
||||
// Find the last ram address in physical space ... this bypasses mapping
|
||||
// but could run into non-ram objects right above ram. Usually systems
|
||||
// aren't designed like that though.
|
||||
for (physAddr = 0x40000, change = newStore;
|
||||
(physAddr < 0x80000000) && (change == newStore);
|
||||
physAddr += 1 << 12)
|
||||
{
|
||||
oldStore = GetPhys(physAddr);
|
||||
newStore = (physAddr & 0x1000) ? 0x55aa55aa : 0xaa55aa55;
|
||||
SetPhys(physAddr, newStore);
|
||||
change = GetPhys(physAddr);
|
||||
SetPhys(physAddr, oldStore);
|
||||
}
|
||||
// Back off by one page
|
||||
physAddr -= 0x1000;
|
||||
BiosMemoryMap[0].BaseAddress = 0x30000; // End of ppcmmu
|
||||
BiosMemoryMap[0].Type = BiosMemoryUsable;
|
||||
BiosMemoryMap[0].Length = physAddr - BiosMemoryMap[0].BaseAddress;
|
||||
|
||||
__asm__("mtmsr %0\n" : : "r" (oldmsr));
|
||||
|
||||
mem_range_end = physAddr;
|
||||
|
||||
printf("Actual RAM: %d Mb\n", physAddr >> 20);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Most PReP hardware is in standard locations, based on the corresponding
|
||||
* hardware on PCs. */
|
||||
PCONFIGURATION_COMPONENT_DATA PpcPrepHwDetect() {
|
||||
PCONFIGURATION_COMPONENT_DATA SystemKey;
|
||||
|
||||
/* Create the 'System' key */
|
||||
FldrCreateSystemKey(&SystemKey);
|
||||
|
||||
printf("DetectHardware() Done\n");
|
||||
return SystemKey;
|
||||
}
|
||||
|
||||
VOID
|
||||
PpcPrepHwIdle(VOID)
|
||||
{
|
||||
/* UNIMPLEMENTED */
|
||||
}
|
||||
|
||||
void PpcPrepInit()
|
||||
{
|
||||
MachVtbl.ConsPutChar = PpcPrepPutChar;
|
||||
|
||||
printf("Serial on\n");
|
||||
|
||||
ide_setup( &ide1_desc );
|
||||
|
||||
MachVtbl.DiskReadLogicalSectors = PpcPrepDiskReadLogicalSectors;
|
||||
|
||||
MachVtbl.ConsKbHit = PpcPrepConsKbHit;
|
||||
MachVtbl.ConsGetCh = PpcPrepConsGetCh;
|
||||
|
||||
MachVtbl.VideoClearScreen = PpcPrepVideoClearScreen;
|
||||
MachVtbl.VideoSetDisplayMode = PpcPrepVideoSetDisplayMode;
|
||||
MachVtbl.VideoGetDisplaySize = PpcPrepVideoGetDisplaySize;
|
||||
|
||||
MachVtbl.GetMemoryMap = PpcPrepGetMemoryMap;
|
||||
MachVtbl.HwDetect = PpcPrepHwDetect;
|
||||
MachVtbl.HwIdle = PcPrepHwIdle;
|
||||
|
||||
printf( "FreeLDR version [%s]\n", FrLdrVersionString );
|
||||
|
||||
BootMain( "" );
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
extern struct _pci_desc pci1_desc;
|
||||
extern struct _idectl_desc ide1_desc;
|
||||
extern struct _vga_desc vga1_desc;
|
||||
struct _pci_bar {
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
void sync( void );
|
||||
void PpcPrepInit( void );
|
||||
void ide_seek( void *extension, int low, int high );
|
||||
int ide_read( void *extension, char *buffer, int bytes );
|
||||
void ide_setup( void *extension );
|
||||
|
||||
void print_bar( struct _pci_bar *bar );
|
||||
void pci_setup
|
||||
( PCONFIGURATION_COMPONENT_DATA pci_bus,
|
||||
struct _pci_desc *pci_desc );
|
||||
void pci_read_bar
|
||||
( struct _pci_desc *pci_desc,
|
||||
int bus, int dev, int fn, int bar,
|
||||
struct _pci_bar *bar_data );
|
||||
|
||||
void vga_setup
|
||||
( PCONFIGURATION_COMPONENT_DATA pci_bus,
|
||||
struct _pci_desc *pci_desc, struct _vga_desc *vga_desc,
|
||||
int bus, int dev, int fn );
|
@ -1,106 +0,0 @@
|
||||
#include "freeldr.h"
|
||||
#include "machine.h"
|
||||
#include "ppcmmu/mmu.h"
|
||||
#include "prep.h"
|
||||
|
||||
#define SWAP_W(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
|
||||
|
||||
typedef struct _idectl_desc {
|
||||
int port;
|
||||
long long seekto;
|
||||
int seek_cylinder, seek_head, seek_sector;
|
||||
int cylinders, heads, sectors, bytespersec;
|
||||
} idectl_desc;
|
||||
|
||||
idectl_desc ide1_desc = { 0x800001f0 };
|
||||
|
||||
void ide_seek( void *extension, int low, int high ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
long long seekto = ((((long long)high) << 32) | (low & 0xffffffff));
|
||||
/* order = sector, head, cylinder */
|
||||
desc->seek_sector = seekto % desc->sectors;
|
||||
seekto /= desc->sectors;
|
||||
desc->seek_head = seekto % desc->heads;
|
||||
seekto /= desc->heads;
|
||||
desc->seek_cylinder = seekto;
|
||||
desc->seekto = seekto;
|
||||
}
|
||||
|
||||
/* Thanks chuck moore. This is based on the color forth ide code */
|
||||
/* Wait for ready */
|
||||
void ide_rdy( void *extension ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
while( !(GetPhysByte(desc->port+7) & 0x40) ) sync();
|
||||
}
|
||||
|
||||
void ide_drq( void *extension ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
while( !(GetPhysByte(desc->port+7) & 0x08) ) sync();
|
||||
}
|
||||
|
||||
void ide_bsy( void *extension ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
while( GetPhysByte(desc->port+7) & 0x80 )
|
||||
{
|
||||
printf("Waiting for not busy\n");
|
||||
sync();
|
||||
}
|
||||
}
|
||||
|
||||
int ide_read( void *extension, char *buffer, int bytes ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
short *databuf = (short *)buffer;
|
||||
int inwords;
|
||||
|
||||
ide_bsy( extension );
|
||||
SetPhysByte(desc->port+2, bytes / desc->bytespersec);
|
||||
SetPhysByte(desc->port+3, desc->seek_sector + 1);
|
||||
SetPhysByte(desc->port+4, desc->seek_cylinder);
|
||||
SetPhysByte(desc->port+5, desc->seek_cylinder >> 8);
|
||||
SetPhysByte(desc->port+6, desc->seek_head | 0xa0);
|
||||
SetPhysByte(desc->port+7, 0x20);
|
||||
|
||||
for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
|
||||
databuf[inwords] = GetPhysHalf(desc->port);
|
||||
}
|
||||
|
||||
desc->seekto += desc->bytespersec;
|
||||
ide_seek( extension, desc->seekto, desc->seekto >> 32 );
|
||||
|
||||
return bytes - (bytes % desc->bytespersec);
|
||||
}
|
||||
|
||||
void ide_setup( void *extension ) {
|
||||
idectl_desc *desc = (idectl_desc *)extension;
|
||||
short identbuffer[256];
|
||||
char namebuf[41];
|
||||
short *databuf = (short *)identbuffer, in;
|
||||
int inwords;
|
||||
|
||||
ide_rdy( extension );
|
||||
ide_bsy( extension );
|
||||
desc->bytespersec = 512;
|
||||
SetPhysByte(desc->port+2, 1);
|
||||
SetPhysByte(desc->port+3, 0);
|
||||
SetPhysByte(desc->port+4, 0);
|
||||
SetPhysByte(desc->port+5, 0);
|
||||
SetPhysByte(desc->port+6, 0);
|
||||
SetPhysByte(desc->port+7, 0xec);
|
||||
ide_drq( extension );
|
||||
|
||||
for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
|
||||
in = GetPhysHalf(desc->port);
|
||||
databuf[inwords] = SWAP_W(in);
|
||||
sync();
|
||||
}
|
||||
|
||||
desc->cylinders = identbuffer[1];
|
||||
desc->heads = identbuffer[3];
|
||||
desc->sectors = identbuffer[6];
|
||||
|
||||
/* Debug: Write out hard disc model */
|
||||
|
||||
strncpy(namebuf, (char *)(identbuffer+0x1b), 41);
|
||||
printf("HARD DISC MODEL: %s c,h,s %d,%d,%d\n",
|
||||
namebuf, desc->cylinders, desc->heads, desc->sectors);
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
#include <freeldr.h>
|
||||
#include "prep.h"
|
||||
|
||||
typedef struct _pci_cfg {
|
||||
unsigned long addr;
|
||||
unsigned long data;
|
||||
} pci_cfg;
|
||||
|
||||
typedef struct _pci_desc {
|
||||
pci_cfg *cfg;
|
||||
} pci_desc;
|
||||
|
||||
pci_desc pci1_desc = { (void *)0x80000cf8 };
|
||||
#define rev16(x) ((((x)>>8)&0xff)|(((x)&0xff)<<8))
|
||||
#define rev32(x) ((((x)>>24)&0xff)|(((x)>>8)&0xff00)|(((x)&0xff00)<<8)|(((x)&0xff)<<24))
|
||||
#define pci_addr(bus,dev,fn,reg) \
|
||||
(0x80000000 | \
|
||||
((bus & 0xff) << 16) | \
|
||||
((dev & 0x1f) << 11) | \
|
||||
((fn & 7) << 8) | \
|
||||
(reg & 0xfc))
|
||||
#if 0
|
||||
#define pci_cfg_addr(bus,dev,fn,reg) \
|
||||
((bus == 0) ? \
|
||||
((1 << (dev + 16)) | \
|
||||
(dev << 11) | \
|
||||
(fn << 8) | \
|
||||
((reg & 0xfc) | 1)) : pci_addr(bus,dev,fn,reg))
|
||||
#else
|
||||
#define pci_cfg_addr(bus,dev,fn,reg) pci_addr(bus,dev,fn,reg)
|
||||
#endif
|
||||
unsigned long pci_read( pci_desc *desc, int bus, int dev, int fn, int reg, int len ) {
|
||||
sync();
|
||||
unsigned long save_state = desc->cfg->addr, ret = 0;
|
||||
unsigned long addr = pci_cfg_addr(bus,dev,fn,reg);
|
||||
unsigned long offset = reg & 3;
|
||||
desc->cfg->addr = rev32(addr);
|
||||
sync();
|
||||
switch( len ) {
|
||||
case 4:
|
||||
ret = desc->cfg->data;
|
||||
break;
|
||||
case 2:
|
||||
ret = desc->cfg->data;
|
||||
ret = (ret >> (offset << 3)) & 0xffff;
|
||||
break;
|
||||
case 1:
|
||||
ret = desc->cfg->data;
|
||||
ret = (ret >> (offset << 3)) & 0xff;
|
||||
break;
|
||||
}
|
||||
desc->cfg->addr = save_state;
|
||||
sync();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pci_read_bar( pci_desc *desc, int bus, int dev, int fn, int bar,
|
||||
struct _pci_bar *bar_data ) {
|
||||
bar_data->data = pci_read( desc, bus, dev, fn, 0x10 + (bar * 4), 4 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Imagine: offset 3, len 1
|
||||
* let oldval = 0x12345678 and val = 0xabcd1234;
|
||||
* mask = ((1 << 8) - 1) << 24; // 0xff000000
|
||||
* oldval = (0x12345678 & 0x00ffffff) | (0xabcd1234 & 0xff000000) = 0xab345678;
|
||||
*/
|
||||
void pci_write( pci_desc *desc, int bus, int dev, int fn, int reg, int len, int val ) {
|
||||
unsigned long save_state = desc->cfg->addr;
|
||||
unsigned long addr = pci_cfg_addr(bus,dev,fn,reg);
|
||||
unsigned long offset = reg & 3;
|
||||
unsigned long oldval = pci_read( desc, bus, dev, fn, reg & ~3, 4 );
|
||||
unsigned long mask = ((1 << (len * 8)) - 1) << (offset << 3);
|
||||
oldval = (oldval & ~mask) | ((val << (offset << 3)) & mask);
|
||||
desc->cfg->addr = rev32(addr);
|
||||
sync();
|
||||
desc->cfg->data = rev32(oldval);
|
||||
sync();
|
||||
desc->cfg->addr = save_state;
|
||||
sync();
|
||||
}
|
||||
|
||||
void pci_write_bar( pci_desc *desc, int bus, int dev, int fn, int bar, struct _pci_bar *bar_data ) {
|
||||
pci_write( desc, bus, dev, fn, 0x10 + (bar * 4), 4, bar_data->data );
|
||||
}
|
||||
|
||||
void print_bar( struct _pci_bar *bar ) {
|
||||
printf("BAR: %x\n", bar->data);
|
||||
}
|
||||
|
||||
#define PCI_VENDORID 0
|
||||
#define PCI_DEVICEID 2
|
||||
#define PCI_HEADER_TYPE 0xe
|
||||
#define PCI_BASECLASS 0xb
|
||||
|
||||
void pci_setup( PCONFIGURATION_COMPONENT_DATA pcibus, pci_desc *desc ) {
|
||||
unsigned char type;
|
||||
unsigned short vendor, device, devclass;
|
||||
int funcs, bus, dev, fn;
|
||||
|
||||
pci1_desc.cfg = (pci_cfg *)0x80000cf8;
|
||||
|
||||
printf("PCI Bus:\n");
|
||||
for( bus = 0; bus < 1; bus++ ) {
|
||||
for( dev = 0; dev < 32; dev++ ) {
|
||||
type = pci_read(desc,bus,dev,0,PCI_HEADER_TYPE,1);
|
||||
vendor = pci_read(desc,bus,dev,0,PCI_VENDORID,2);
|
||||
device = pci_read(desc,bus,dev,0,PCI_DEVICEID,2);
|
||||
|
||||
if(vendor == 0 || vendor == 0xffff) continue;
|
||||
if(type & 0x80) funcs = 8; else funcs = 1;
|
||||
|
||||
for( fn = 0; fn < funcs; fn++ ) {
|
||||
devclass = pci_read(desc,bus,dev,fn,PCI_BASECLASS,1);
|
||||
printf(" %d:%d -> vendor:device:class %x:%x:%x\n",
|
||||
bus, dev, vendor, device, devclass);
|
||||
|
||||
if( devclass == 3 ) {
|
||||
printf("Setting up vga...\n");
|
||||
vga_setup(pcibus,desc,&vga1_desc,bus,dev,fn);
|
||||
printf("Done with vga\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("^-- end PCI\n");
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#include <freeldr.h>
|
||||
#include "prep.h"
|
||||
|
||||
struct _vga_desc {
|
||||
char *port;
|
||||
char *addr;
|
||||
};
|
||||
|
||||
#define VGA_WIDTH 1024
|
||||
#define VGA_HEIGHT 768
|
||||
struct _vga_desc vga1_desc = { (char *)0x800003c0 };
|
||||
|
||||
void vga_setup( PCONFIGURATION_COMPONENT_DATA pcibus,
|
||||
struct _pci_desc *desc, struct _vga_desc *vga_desc,
|
||||
int bus, int dev, int fn ) {
|
||||
struct _pci_bar bar_data;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 6; i++ ) {
|
||||
pci_read_bar( desc, bus, dev, fn, i, &bar_data );
|
||||
print_bar( &bar_data );
|
||||
if( (bar_data.data > 0x10000) || ((bar_data.data&1) == 1) ) {
|
||||
vga_desc->addr = (char *)(0xc0000000 + (bar_data.data & ~0x7ff));
|
||||
// BootInfo.dispDeviceBase = vga_desc->addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2003 Eric Kohl
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __REGISTRY_H
|
||||
#include "../../reactos/registry.h"
|
||||
#endif
|
||||
|
||||
/* PROTOTYPES ***************************************************************/
|
||||
|
||||
/* hardware.c */
|
||||
|
||||
VOID StallExecutionProcessor(ULONG Microseconds);
|
||||
|
||||
VOID HalpCalibrateStallExecution(VOID);
|
||||
|
||||
ULONGLONG RDTSC(VOID);
|
||||
|
||||
/* EOF */
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define OF_FAILED 0
|
||||
#define ERR_NOT_FOUND 0xc0000010
|
||||
|
||||
#include "of_call.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef int (*of_proxy)
|
||||
( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6 );
|
||||
typedef long jmp_buf[100];
|
||||
extern of_proxy ofproxy;
|
||||
|
||||
int setjmp( jmp_buf buf );
|
||||
int longjmp( jmp_buf buf, int retval );
|
||||
int ofw_callmethod_ret(const char *method, int handle, int nargs, int *args, int ret);
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
@ -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 */
|
@ -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
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
||||
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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);
|
@ -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
|
@ -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;
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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>
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define Ke386SaveFlags(x) __asm__ __volatile__("mfmsr %0" : "=r" (x) :)
|
||||
|
||||
/* EOF */
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
@ -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 */
|
@ -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() { }
|
@ -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
|
||||
}
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
@ -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();
|
||||
}
|
||||
|
@ -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_)
|
||||
|
@ -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(©, 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*/
|
@ -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*/
|
@ -34,7 +34,6 @@ endif()
|
||||
add_subdirectory(ioevent)
|
||||
add_subdirectory(lsalib)
|
||||
add_subdirectory(nt)
|
||||
add_subdirectory(ppcmmu)
|
||||
add_subdirectory(pseh)
|
||||
|
||||
if(KDBG)
|
||||
|
@ -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})
|
||||
|
@ -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 */
|
@ -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
|
@ -1,8 +0,0 @@
|
||||
|
||||
list(APPEND SOURCE dummy.c)
|
||||
|
||||
if(ARCH STREQUAL "powerpc")
|
||||
list(APPEND SOURCE mmuutil.c)
|
||||
endif()
|
||||
|
||||
add_library(ppcmmu ${SOURCE})
|
@ -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
|
@ -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 */
|
@ -1,8 +0,0 @@
|
||||
OUTPUT_FORMAT(elf32-powerpc);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) *(.rodata) }
|
||||
.bss : { *(.sbss) *(.bss) *(COMMON) }
|
||||
}
|
@ -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 ! */
|
||||
}
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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})
|
||||
|
@ -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
|
@ -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})
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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 */
|
Loading…
Reference in New Issue
Block a user