diff --git a/reactos/Makefile b/reactos/Makefile
index 6fb7488618b..4c64926fd85 100644
--- a/reactos/Makefile
+++ b/reactos/Makefile
@@ -414,7 +414,11 @@ PREAUTO := \
$(ERRCODES_H) \
$(ERRCODES_RC) \
$(GENDIB_DIB_FILES) \
- $(NCI_SERVICE_FILES)
+ $(NCI_SERVICE_FILES) \
+ $(OFW_INTERFACE_SERVICE_FILES)
+ifeq ($(ARCH),powerpc)
+PREAUTO += $(PPCMMU_TARGETS)
+endif
$(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES)
${mkdir} $(OUTPUT_)media$(SEP)inf 2>$(NUL)
diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild
index 26891addcac..092cbc3aa4a 100644
--- a/reactos/ReactOS-ppc.rbuild
+++ b/reactos/ReactOS-ppc.rbuild
@@ -9,22 +9,27 @@
-
-
-
-
+
-
+
- -v
- -Wpointer-arith
+
+ 1
+
+ -fshort-wchar
+ -fsigned-char
+ -mfull-toc
+ -meabi
+ -O2
+ -Wno-strict-aliasing
+ -Wno-trampolines
diff --git a/reactos/boot/freeldr/bootsect/bootsect.rbuild b/reactos/boot/freeldr/bootsect/bootsect.rbuild
index 65334cc0be4..b3b7f2f3c47 100644
--- a/reactos/boot/freeldr/bootsect/bootsect.rbuild
+++ b/reactos/boot/freeldr/bootsect/bootsect.rbuild
@@ -22,9 +22,3 @@
isobtrt.asm
-
-
-
- ofwboot.s
-
-
\ No newline at end of file
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
index a507daafab4..7efff45fb7b 100644
--- a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
@@ -1,3 +1,103 @@
+ .section ".text"
.extern PpcInit
+ .globl _start
+ .globl call_ofw
_start:
- b PpcInit+4
+ 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 bootme
+
+ lis %r3,call_ofw@ha
+ addi %r3,%r3,call_ofw@l
+
+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 ".bss"
+_bss:
+ .long 0
+
+ .align 4
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h
new file mode 100644
index 00000000000..66797a6929d
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h
@@ -0,0 +1,108 @@
+#ifndef _FREELDR_ARCH_COMPAT_H
+#define _FREELDR_ARCH_COMPAT_H
+
+#define __init
+#define __initdata
+
+#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
+#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
+#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
+#define SPRN_LDSTDB 0x3f4 /* */
+#define SPRN_LR 0x008 /* Link Register */
+#ifndef SPRN_PIR
+#define SPRN_PIR 0x3FF /* Processor Identification Register */
+#endif
+#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
+#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
+#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
+#define SPRN_PVR 0x11F /* Processor Version Register */
+#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
+#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
+#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
+#define SPRN_ASR 0x118 /* Address Space Register */
+#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
+#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
+#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
+#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
+#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
+#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
+#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
+#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
+#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
+#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
+#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
+#ifndef SPRN_SVR
+#define SPRN_SVR 0x11E /* System Version Register */
+#endif
+#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */
+/* these bits were defined in inverted endian sense originally, ugh, confusing */
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX 0 /* Supervisor read/write, User none */
+#define PP_RWRX 1 /* Supervisor read/write, User read */
+#define PP_RWRW 2 /* Supervisor read/write, User read/write */
+#define PP_RXRX 3 /* Supervisor read, User read */
+
+/* Block size masks */
+#define BL_128K 0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M 0x007
+#define BL_2M 0x00F
+#define BL_4M 0x01F
+#define BL_8M 0x03F
+#define BL_16M 0x07F
+#define BL_32M 0x0FF
+#define BL_64M 0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* BAT Access Protection */
+#define BPP_XX 0x00 /* No access */
+#define BPP_RX 0x01 /* Read only */
+#define BPP_RW 0x02 /* Read/write */
+
+/* Definitions for 40x embedded chips. */
+#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
+#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
+#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
+#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
+#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
+#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
+#define _PAGE_RW 0x040 /* software: Writes permitted */
+#define _PAGE_DIRTY 0x080 /* software: dirty page */
+#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
+#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
+
+#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
+#define _PMD_BAD 0x802
+#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M 0x0c0
+#define _PMD_SIZE_16M 0x0e0
+#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+#define PVR_VER(pvr)(((pvr) >> 16) & 0xFFFF) /* Version field */
+
+#define KERNELBASE 0x80000000
+
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+
+typedef struct _pci_reg_property {
+ struct {
+ int a_hi, a_mid, a_lo;
+ } addr;
+ int size_hi, size_lo;
+} pci_reg_property;
+
+void btext_drawstring(const char *c);
+void btext_drawhex(unsigned long v);
+
+void *ioremap(__u32 phys, __u32 size);
+void iounmap(void *logical);
+
+__u32 GetPVR();
+
+#endif/*_FREELDR_ARCH_COMPAT_H*/
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/loader.c b/reactos/boot/freeldr/freeldr/arch/powerpc/loader.c
new file mode 100644
index 00000000000..0dea8ef0ca9
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/loader.c
@@ -0,0 +1,349 @@
+/*
+ * FreeLoader
+ * Copyright (C) 1998-2003 Brian Palmer
+ * Copyright (C) 2005 Alex Ionescu
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define _NTSYSTEM_
+#include
+
+#define NDEBUG
+#include
+#undef DbgPrint
+
+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)
+ {
+ DbgPrint("Forward: %s\n", (PCHAR)Function);
+ 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 + (KSEG0_BASE - (ULONG_PTR)KernelMemory));
+
+ //DbgPrint("Looked for: %s and found: %p\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;
+
+ printf("Fixing up %x (%s)\n", DllBase, DllName);
+
+ /* 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;
+}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
index c79d5062bc7..de937c04bd0 100644
--- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
@@ -18,123 +18,32 @@
*/
#include "freeldr.h"
#include "machine.h"
+#include "ppcmmu/mmu.h"
#include "of.h"
+#include "ppcboot.h"
+#include "prep.h"
+#include "compat.h"
-extern void BootMain( char * );
-extern char *GetFreeLoaderVersionString();
+extern void BootMain( LPSTR CmdLine );
+extern PCHAR GetFreeLoaderVersionString();
+extern ULONG CacheSizeLimit;
of_proxy ofproxy;
void *PageDirectoryStart, *PageDirectoryEnd;
-static int chosen_package, stdin_handle, part_handle = -1;
+static int chosen_package, stdin_handle, stdout_handle,
+ part_handle = -1, kernel_mem = 0;
+int mmu_handle = 0, FixedMemory = 0;
BOOLEAN AcpiPresent = FALSE;
-char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
+char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { "bootprep" };
jmp_buf jmp;
+volatile char *video_mem = 0;
+boot_infos_t BootInfo;
-void le_swap( const void *start_addr_v,
- const void *end_addr_v,
- const void *target_addr_v ) {
- long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8),
- *end_addr = (long *)ROUND_UP((long)end_addr_v,8),
- *target_addr = (long *)ROUND_DOWN((long)target_addr_v,8);
- long tmp;
- while( start_addr <= end_addr ) {
- tmp = start_addr[0];
- target_addr[0] = REV(start_addr[1]);
- target_addr[1] = REV(tmp);
- start_addr += 2;
- target_addr += 2;
- }
-}
-
-int ofw_finddevice( const char *name ) {
- int ret, len;
-
- len = strlen(name);
- le_swap( name, name + len, name );
- ret = ofproxy( 0, (char *)name, NULL, NULL, NULL );
- le_swap( name, name + len, name );
- return ret;
-}
-
-int ofw_getprop( int package, const char *name, void *buffer, int buflen ) {
- int ret, len = strlen(name);
- le_swap( name, name + len, name );
- le_swap( buffer, (char *)buffer + buflen, buffer );
- ret = ofproxy
- ( 4, (void *)package, (char *)name, buffer, (void *)buflen );
- le_swap( buffer, (char *)buffer + buflen, buffer );
- le_swap( name, name + len, name );
- return ret;
-}
-
-/* Since this is from external storage, it doesn't need swapping */
-int ofw_write( int handle, const char *data, int len ) {
- int ret;
- le_swap( data, data + len, data );
- ret = ofproxy
- ( 8, (void *)handle, (char *)data, (void *)len, NULL );
- le_swap( data, data + len, data );
- return ret;
-}
-
-/* Since this is from external storage, it doesn't need swapping */
-int ofw_read( int handle, const char *data, int len ) {
- int ret;
-
- le_swap( data, data + len, data );
- ret = ofproxy
- ( 12, (void *)handle, (char *)data, (void *)len, NULL );
- le_swap( data, data + len, data );
-
- return ret;
-}
-
-void ofw_exit() {
- ofproxy( 16, NULL, NULL, NULL, NULL );
-}
-
-void ofw_dumpregs() {
- ofproxy( 20, NULL, NULL, NULL, NULL );
-}
-
-void ofw_print_string( const char *str ) {
- int len = strlen(str);
- le_swap( (char *)str, str + len, (char *)str );
- ofproxy( 24, (void *)str, NULL, NULL, NULL );
- le_swap( (char *)str, str + len, (char *)str );
-}
-
-void ofw_print_number( int num ) {
- ofproxy( 28, (void *)num, NULL, NULL, NULL );
-}
-
-int ofw_open( const char *name ) {
- int ret, len;
-
- len = strlen(name);
- le_swap( name, name + len, name );
- ret = ofproxy( 32, (char *)name, NULL, NULL, NULL );
- le_swap( name, name + len, name );
- return ret;
-}
-
-int ofw_child( int package ) {
- return ofproxy( 36, (void *)package, NULL, NULL, NULL );
-}
-
-int ofw_peer( int package ) {
- return ofproxy( 40, (void *)package, NULL, NULL, NULL );
-}
-
-int ofw_seek( int handle, long long location ) {
- return ofproxy( 44, (void *)handle, (void *)(int)(location >> 32), (void *)(int)location, NULL );
-}
-
-void PpcPutChar( int ch ) {
+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_print_string( buf );
+ ofw_write(stdout_handle, buf, strlen(buf));
}
int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
@@ -156,7 +65,7 @@ int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
if( !nth && match ) return parent;
- for( i = 0; i < depth; i++ ) PpcPutChar( ' ' );
+ for( i = 0; i < depth; i++ ) PpcOfwPutChar( ' ' );
if( depth == 1 ) {
if( gotname > 0 ) {
@@ -176,7 +85,7 @@ int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
}
BOOLEAN PpcConsKbHit() {
- return TRUE;
+ return FALSE;
}
int PpcConsGetCh() {
@@ -186,29 +95,28 @@ int PpcConsGetCh() {
}
void PpcVideoClearScreen( UCHAR Attr ) {
- ofw_print_string("ClearScreen\n");
}
-VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
- printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
- return VideoGraphicsMode;
-}
-
-/* FIXME: Query */
VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
- ofw_print_string("GetDisplaySize\n");
- *Width = 640;
- *Height = 480;
- *Depth = 8;
+ *Width = 80;
+ *Height = 25;
+ *Depth = 16;
}
ULONG PpcVideoGetBufferSize() {
ULONG Width, Height, Depth;
- ofw_print_string("PpcVideoGetBufferSize\n");
- PpcVideoGetDisplaySize( &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);
}
@@ -222,7 +130,22 @@ VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) {
}
VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
- printf( "CopyOffScreenBufferToVRAM(%x)\n", 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() {
@@ -243,27 +166,187 @@ VOID PpcVideoSync() {
printf( "Sync\n" );
}
-VOID PpcVideoPrepareForReactOS() {
- printf( "PrepareForReactOS\n");
+static int prom_next_node(int *nodep)
+{
+ int node;
+
+ if ((node = *nodep) != 0
+ && (*nodep = ofw_child(node)) != 0)
+ return 1;
+ if ((*nodep = ofw_peer(node)) != 0)
+ return 1;
+ for (;;) {
+ if ((node = ofw_parent(node)) == 0)
+ return 0;
+ if ((*nodep = ofw_peer(node)) != 0)
+ return 1;
+ }
}
-/* XXX FIXME:
- * According to the linux people (this is backed up by my own experience),
- * the memory object in older ofw does not do getprop right.
- *
- * The "right" way is to probe the pci bridge. *sigh*
+
+/* Appropriated from linux' btext.c
+ * author:
+ * Benjamin Herrenschmidt
+ */
+VOID PpcVideoPrepareForReactOS(BOOLEAN Setup) {
+ int i, j, k, /* display_handle, */ display_package, display_size = 0;
+ int node, ret, elts;
+ int device_address;
+ //pci_reg_property display_regs[8];
+ char type[256], path[256], name[256];
+ char logo[] = {
+ " "
+ " XXXXXX "
+ " X X "
+ " X X X X "
+ " X X "
+ " X XXXX X "
+ " X XX X "
+ " X X "
+ " XXXXXX "
+ " "
+ };
+ int logo_x = 10, logo_y = 10;
+ int logo_scale_x = 8, logo_scale_y = 8;
+
+
+ for( node = ofw_finddevice("/"); prom_next_node(&node); ) {
+ memset(type, 0, sizeof(type));
+ memset(path, 0, sizeof(path));
+
+ ret = ofw_getprop(node, "name", name, sizeof(name));
+
+ if(ofw_getprop(node, "device_type", type, sizeof(type)) <= 0) {
+ printf("Could not get type for node %x\n", node);
+ continue;
+ }
+
+ printf("Node %x ret %d name %s type %s\n", node, ret, name, type);
+
+ if(strcmp(type, "display") == 0) break;
+ }
+
+ if(!node) return;
+
+ if(ofw_package_to_path(node, path, sizeof(path)) < 0) {
+ printf("could not get path for display package %x\n", node);
+ return;
+ }
+
+ printf("Opening display package: %s\n", path);
+ display_package = ofw_finddevice(path);
+ printf("display package %x\n", display_package);
+
+ BootInfo.dispDeviceRect[0] = BootInfo.dispDeviceRect[1] = 0;
+
+ ofw_getprop(display_package, "width",
+ (void *)&BootInfo.dispDeviceRect[2], sizeof(int));
+ ofw_getprop(display_package, "height",
+ (void *)&BootInfo.dispDeviceRect[3], sizeof(int));
+ ofw_getprop(display_package, "depth",
+ (void *)&BootInfo.dispDeviceDepth, sizeof(int));
+ ofw_getprop(display_package, "linebytes",
+ (void *)&BootInfo.dispDeviceRowBytes, sizeof(int));
+
+ BootInfo.dispDeviceRect[2] = BootInfo.dispDeviceRect[2];
+ BootInfo.dispDeviceRect[3] = BootInfo.dispDeviceRect[3];
+ BootInfo.dispDeviceDepth = BootInfo.dispDeviceDepth;
+ BootInfo.dispDeviceRowBytes = BootInfo.dispDeviceRowBytes;
+
+ if(ofw_getprop
+ (display_package,
+ "address",
+ (void *)&device_address,
+ sizeof(device_address)) < 1) {
+ printf("Could not get device base\n");
+ return;
+ }
+
+ BootInfo.dispDeviceBase = (PVOID)(device_address);
+
+ display_size = BootInfo.dispDeviceRowBytes * BootInfo.dispDeviceRect[3];
+
+ printf("Display size is %x bytes (%x per row times %x rows)\n",
+ display_size,
+ BootInfo.dispDeviceRowBytes,
+ BootInfo.dispDeviceRect[3]);
+
+ printf("display is at %x\n", BootInfo.dispDeviceBase);
+
+ for( i = 0; i < logo_y * logo_scale_y; i++ ) {
+ for( j = 0; j < logo_x * logo_scale_x; j++ ) {
+ elts = (j/logo_scale_x) + ((i/logo_scale_y) * logo_x);
+
+ for( k = 0; k < BootInfo.dispDeviceDepth/8; k++ ) {
+ SetPhysByte(((ULONG_PTR)BootInfo.dispDeviceBase)+
+ k +
+ ((j * (BootInfo.dispDeviceDepth/8)) +
+ (i * (BootInfo.dispDeviceRowBytes))),
+ logo[elts] == ' ' ? 0 : 255);
+ }
+ }
+ }
+}
+
+/*
+ * Get memory the proper openfirmware way
*/
ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize ) {
- printf("GetMemoryMap(chosen=%x)\n", chosen_package);
+ int i, memhandle, returned, total = 0, slots = 0;
+ int memdata[0x40];
- BiosMemoryMap[0].Type = BiosMemoryUsable;
- BiosMemoryMap[0].BaseAddress = 0;
- BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */
+ printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
- printf( "Returning memory map (%dk total)\n",
- (int)BiosMemoryMap[0].Length / 1024 );
+ memhandle = ofw_finddevice("/memory");
- return 1;
+ returned = ofw_getprop(memhandle, "available",
+ (char *)memdata, sizeof(memdata));
+
+ printf("Returned data: %d\n", returned);
+ if( returned == -1 ) {
+ printf("getprop /memory[@reg] failed\n");
+ return 0;
+ }
+
+ for( i = 0; i < returned; i++ ) {
+ printf("%x ", memdata[i]);
+ }
+ printf("\n");
+
+ for( i = 0; i < returned / 2; i++ ) {
+ BiosMemoryMap[slots].Type = 1/*MEMTYPE_USABLE*/;
+ BiosMemoryMap[slots].BaseAddress = memdata[i*2];
+ BiosMemoryMap[slots].Length = memdata[i*2+1];
+ printf("MemoryMap[%d] = (%x:%x)\n",
+ i,
+ (int)BiosMemoryMap[slots].BaseAddress,
+ (int)BiosMemoryMap[slots].Length);
+
+ /* Hack for pearpc */
+ if( kernel_mem ) {
+ BiosMemoryMap[slots].Length = kernel_mem * 1024;
+ if( !FixedMemory ) {
+ ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
+ (int)BiosMemoryMap[slots].Length,
+ 0x1000);
+ FixedMemory = BiosMemoryMap[slots].BaseAddress;
+ }
+ total += BiosMemoryMap[slots].Length;
+ slots++;
+ break;
+ /* Normal way */
+ } else if( BiosMemoryMap[slots].Length &&
+ ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
+ (int)BiosMemoryMap[slots].Length,
+ 0x1000) ) {
+ total += BiosMemoryMap[slots].Length;
+ slots++;
+ }
+ }
+
+ printf( "Returning memory map (%dk total)\n", total / 1024 );
+
+ return slots;
}
/* Strategy:
@@ -288,7 +371,14 @@ BOOLEAN PpcDiskGetSystemVolume( char *SystemPath,
PULONGLONG StartSector,
PULONGLONG SectorCount,
int *FsType ) {
- return FALSE;
+ char *remain = strchr(SystemPath, '\\');
+ if( remain ) {
+ strcpy( RemainingPath, remain+1 );
+ } else {
+ RemainingPath[0] = 0;
+ }
+ *Device = 0;
+ return MachDiskGetBootVolume(DriveNumber, StartSector, SectorCount, FsType);
}
BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) {
@@ -305,7 +395,7 @@ BOOLEAN PpcDiskBootingFromFloppy(VOID) {
}
BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
- ULONG SectorCount, PVOID Buffer ) {
+ ULONG SectorCount, PVOID Buffer ) {
int rlen = 0;
if( part_handle == -1 ) {
@@ -322,11 +412,14 @@ BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
return FALSE;
}
- if( ofw_seek( part_handle, SectorNumber * 512 ) ) {
- printf("Seek to %x failed\n", SectorNumber * 512);
+ 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, SectorCount * 512 );
+
+ rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) );
return rlen > 0;
}
@@ -351,31 +444,75 @@ ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day,
PULONG Hour, PULONG Minute, PULONG Second ) {
- printf("RTCGeturrentDateTime\n");
+ //printf("RTCGeturrentDateTime\n");
}
VOID PpcHwDetect() {
printf("PpcHwDetect\n");
}
+BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) {
+ CHAR BootPath[256];
+ ULONG PartitionNumber;
+ ULONG DriveNumber;
+ PARTITION_TABLE_ENTRY PartEntry;
+ char *p;
+
+ if (!DissectArcPath(SystemPath, BootPath, &DriveNumber, &PartitionNumber))
+ {
+ return FALSE;
+ }
+
+ if (0 != PartitionNumber)
+ {
+ return TRUE;
+ }
+
+ if (! DiskGetActivePartitionEntry(DriveNumber,
+ &PartEntry,
+ &PartitionNumber) ||
+ PartitionNumber < 1 || 9 < PartitionNumber)
+ {
+ return FALSE;
+ }
+
+ p = SystemPath;
+ while ('\0' != *p && 0 != _strnicmp(p, "partition(", 10)) {
+ p++;
+ }
+ p = strchr(p, ')');
+ if (NULL == p || '0' != *(p - 1)) {
+ return FALSE;
+ }
+ *(p - 1) = '0' + PartitionNumber;
+
+ return TRUE;
+}
+
+extern int _bss;
typedef unsigned int uint32_t;
-void PpcInit( of_proxy the_ofproxy ) {
- int len;
- ofproxy = the_ofproxy;
-
+void PpcOfwInit()
+{
chosen_package = ofw_finddevice( "/chosen" );
+ ofw_getprop(chosen_package, "bootargs",
+ CmdLine, sizeof(CmdLine));
ofw_getprop( chosen_package, "stdin",
- &stdin_handle, sizeof(stdin_handle) );
+ (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) );
- stdin_handle = REV(stdin_handle);
-
- MachVtbl.ConsPutChar = PpcPutChar;
+ MachVtbl.ConsPutChar = PpcOfwPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
-
- printf( "stdin_handle is %x\n", stdin_handle );
+
+ printf( "chosen_package %x, stdin_handle is %x\n",
+ chosen_package, stdin_handle );
+ printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0));
+ printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0));
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
@@ -394,6 +531,7 @@ void PpcInit( of_proxy the_ofproxy ) {
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+ MachVtbl.DiskNormalizeSystemPath = PpcDiskNormalizeSystemPath;
MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume;
MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume;
MachVtbl.DiskGetBootPath = PpcDiskGetBootPath;
@@ -408,19 +546,27 @@ void PpcInit( of_proxy the_ofproxy ) {
MachVtbl.HwDetect = PpcHwDetect;
+ // Allow forcing prep for broken OFW
+ if(!strncmp(CmdLine, "bootprep", 8))
+ {
+ printf("Going to PREP init...\n");
+ PpcPrepInit();
+ return;
+ }
+
printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
- len = ofw_getprop(chosen_package, "bootargs",
- CmdLine, sizeof(CmdLine));
-
- if( len < 0 ) len = 0;
- CmdLine[len] = 0;
-
BootMain( CmdLine );
}
+void PpcInit( of_proxy the_ofproxy ) {
+ ofproxy = the_ofproxy;
+ if(ofproxy) PpcOfwInit();
+ else PpcPrepInit();
+}
+
void MachInit(const char *CmdLine) {
- int len, i;
+ int i, len;
char *sep;
BootPart[0] = 0;
@@ -428,15 +574,19 @@ void MachInit(const char *CmdLine) {
printf( "Determining boot device: [%s]\n", CmdLine );
- printf( "Boot Args: %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, ' ');
+ sep = strchr(BootPart, ',');
if( sep )
*sep = 0;
- break;
+ while(CmdLine[i] && CmdLine[i]!=',') i++;
+ }
+ if( strncmp(CmdLine + i, "mem=", 4) == 0) {
+ kernel_mem = atoi(CmdLine+i+4);
+ printf("Allocate %dk kernel memory\n", kernel_mem);
+ while(CmdLine[i] && CmdLine[i]!=',') i++;
}
}
@@ -464,10 +614,11 @@ void beep() {
}
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address) {
- return 0xff;
+ return GetPhysByte(((ULONG)Address)+0x80000000);
}
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
+ SetPhysByte(((ULONG)Address)+0x80000000, Value);
}
void DiskStopFloppyMotor() {
@@ -484,3 +635,7 @@ void BootNewLinuxKernel() {
void ChainLoadBiosBootSectorCode() {
ofw_exit();
}
+
+void DbgBreakPoint() {
+ ofw_exit();
+}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
index 23997df7c78..17de0f61daa 100644
--- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
@@ -1,65 +1,74 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: Freeloader
- * FILE: boot/freeldr/freeldr/multiboot.c
- * PURPOSE: ReactOS Loader
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * FreeLoader
+ * Copyright (C) 1998-2003 Brian Palmer
+ * Copyright (C) 2005 Alex Ionescu
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include
-#include
+#include
+#include
+#include
+#include "ppcboot.h"
+#include "ppcmmu/mmu.h"
+#include "compat.h"
+#include "ppcfont.h"
#define NDEBUG
#include
-/* Base Addres of Kernel in Physical Memory */
-#define KERNEL_BASE_PHYS 0x200000
+PVOID KernelMemory = 0;
+extern boot_infos_t BootInfo;
/* 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 20
+#define PDE_SHIFT 22
#define PDE_SHIFT_PAE 18
-
-/* Converts a Relative Address read from the Kernel into a Physical Address */
-#define RaToPa(p) \
- (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS)
-
-/* Converts a Phsyical Address Pointer into a Page Frame Number */
-#define PaPtrToPfn(p) \
- (((ULONG_PTR)&p) >> PFN_SHIFT)
-
-/* Converts a Phsyical Address into a Page Frame Number */
-#define PaToPfn(p) \
- ((p) >> PFN_SHIFT)
-
-#define STARTUP_BASE 0xF0000000
-#define HYPERSPACE_BASE 0xF0800000
+#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 >> 20) / sizeof(HARDWARE_PTE_X86)
-#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
-#define KpcrPageTableIndex (KPCR_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
-#define ApicPageTableIndex (APIC_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
+#define StartupPageTableIndex (STARTUP_BASE >> 22)
+#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22)
+#define KpcrPageTableIndex (KPCR_BASE >> 22)
+#define ApicPageTableIndex (APIC_BASE >> 22)
#define LowMemPageTableIndexPae 0
#define StartupPageTableIndexPae (STARTUP_BASE >> 21)
-#define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21)
+#define HyperspacePageTableIndexPae (HYPERSPACE_PAE_BASE >> 21)
#define KpcrPageTableIndexPae (KPCR_BASE >> 21)
#define ApicPageTableIndexPae (APIC_BASE >> 21)
+#define BAT_GRANULARITY (64 * 1024)
+#define KernelMemorySize (8 * 1024 * 1024)
#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase
+#define XROUNDUP(x,n) ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
/* Load Address of Next Module */
ULONG_PTR NextModuleBase = 0;
/* Currently Opened Module */
-VOID *CurrentModule = NULL;
+PLOADER_MODULE CurrentModule = NULL;
/* Unrelocated Kernel Base in Virtual Memory */
ULONG_PTR KernelBase;
@@ -70,10 +79,22 @@ BOOLEAN PaeModeEnabled;
/* Kernel Entrypoint in Physical Memory */
ULONG_PTR KernelEntry;
+/* Dummy to bring in memmove */
+PVOID memmove_dummy = memmove;
+
+PLOADER_MODULE
+NTAPI
+LdrGetModuleObject(PCHAR ModuleName);
+
+NTSTATUS
+NTAPI
+LdrPEFixupImports(IN PVOID DllBase,
+ IN PCHAR DllName);
+
/* FUNCTIONS *****************************************************************/
/*++
- * FrLdrStartup
+ * FrLdrStartup
* INTERNAL
*
* Prepares the system for loading the Kernel.
@@ -88,24 +109,128 @@ ULONG_PTR KernelEntry;
* None.
*
*--*/
+
+typedef void (*KernelEntryFn)( void * );
+
+int MmuPageMiss(int inst, ppc_trap_frame_t *trap)
+{
+ int i;
+ printf("inst %x\n", inst);
+ for( i = 0; i < 40; i++ )
+ printf("r[%d] %x\n", i, trap->gpr[i]);
+ printf("HALT!\n");
+ while(1);
+}
+
VOID
NTAPI
FrLdrStartup(ULONG Magic)
-{
-#if 0
- /* Disable Interrupts */
- KeArchDisableInterrupts();
-
- /* Re-initalize EFLAGS */
- KeArchEraseFlags();
-
- /* Initialize the page directory */
- FrLdrSetupPageDirectory();
-#endif
+{
+ KernelEntryFn KernelEntryAddress =
+ (KernelEntryFn)(KernelEntry + KernelBase);
+ ULONG_PTR i, j, page, count;
+ PCHAR ModHeader;
+ boot_infos_t *LocalBootInfo = &BootInfo;
+ LocalBootInfo->dispFont = (font_char *)&LocalBootInfo[1];
+ LoaderBlock.ArchExtra = (ULONG)LocalBootInfo;
+ ppc_map_info_t *info = MmAllocateMemory(0x80 * sizeof(*info));
+
+ for(i = 0; i < LoaderBlock.ModsCount; i++)
+ {
+ ModHeader = ((PCHAR)reactos_modules[i].ModStart);
+ if(ModHeader[0] == 'M' && ModHeader[1] == 'Z')
+ LdrPEFixupImports
+ ((PVOID)reactos_modules[i].ModStart,
+ (PCHAR)reactos_modules[i].String);
+ }
+
+ /* We'll use vsid 1 for freeldr (expendable) */
+ MmuAllocVsid(1, 0xff);
+ MmuSetVsid(0, 8, 1);
+
+ MmuAllocVsid(0, 0xff00);
+ MmuSetVsid(8, 16, 0);
+
+ MmuSetPageCallback(MmuPageMiss);
+
+ info = MmAllocateMemory((KernelMemorySize >> PAGE_SHIFT) * sizeof(*info));
+
+ /* Map kernel space 0x80000000 ... */
+ for( i = (ULONG)KernelMemory, page = 0;
+ i < (ULONG)KernelMemory + KernelMemorySize;
+ i += (1<> 21);
-
- /* Get the Startup Page Directory Table */
- PageDirTablePae = (PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae;
-
- /* Get the Startup Page Directory */
- PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae;
-
- /* Set the Startup page directory table */
- for (i = 0; i < 4; i++)
- {
- PageDirTablePae->Pde[i].Valid = 1;
- PageDirTablePae->Pde[i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
- }
-
- /* Set up the Low Memory PDE */
- for (i = 0; i < 2; i++)
- {
- PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1;
- PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1;
- PageDirPae->Pde[LowMemPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i;
- }
-
- /* Set up the Kernel PDEs */
- for (i = 0; i < 3; i++)
- {
- PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1;
- PageDirPae->Pde[KernelPageTableIndex + i].Write = 1;
- PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber = PaPtrToPfn(kernel_pagetable_pae) + i;
- }
-
- /* Set up the Startup PDE */
- for (i = 0; i < 4; i++)
- {
- PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1;
- PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1;
- PageDirPae->Pde[StartupPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
- }
-
- /* Set up the Hyperspace PDE */
- for (i = 0; i < 2; i++)
- {
- PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1;
- PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1;
- PageDirPae->Pde[HyperspacePageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i;
- }
-
- /* Set up the Apic PDE */
- for (i = 0; i < 2; i++)
- {
- PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1;
- PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1;
- PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(apic_pagetable_pae) + i;
- }
-
- /* Set up the KPCR PDE */
- PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1;
- PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1;
- PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber = PaPtrToPfn(kpcr_pagetable_pae);
-
- /* Set up Low Memory PTEs */
- PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae;
- for (i=0; i<1024; i++) {
-
- PageDirPae->Pde[i].Valid = 1;
- PageDirPae->Pde[i].Write = 1;
- PageDirPae->Pde[i].Owner = 1;
- PageDirPae->Pde[i].PageFrameNumber = i;
- }
-
- /* Set up Kernel PTEs */
- PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae;
- for (i=0; i<1536; i++) {
-
- PageDirPae->Pde[i].Valid = 1;
- PageDirPae->Pde[i].Write = 1;
- PageDirPae->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS) + i;
- }
-
- /* Set up APIC PTEs */
- PageDirPae = (PPAGE_DIRECTORY_X64)&apic_pagetable_pae;
- PageDirPae->Pde[0].Valid = 1;
- PageDirPae->Pde[0].Write = 1;
- PageDirPae->Pde[0].CacheDisable = 1;
- PageDirPae->Pde[0].WriteThrough = 1;
- PageDirPae->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
- PageDirPae->Pde[0x200].Valid = 1;
- PageDirPae->Pde[0x200].Write = 1;
- PageDirPae->Pde[0x200].CacheDisable = 1;
- PageDirPae->Pde[0x200].WriteThrough = 1;
- PageDirPae->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
-
- /* Set up KPCR PTEs */
- PageDirPae = (PPAGE_DIRECTORY_X64)&kpcr_pagetable_pae;
- PageDirPae->Pde[0].Valid = 1;
- PageDirPae->Pde[0].Write = 1;
- PageDirPae->Pde[0].PageFrameNumber = 1;
-
- } else {
-
- /* Get the Kernel Table Index */
- KernelPageTableIndex = (KernelBase >> PDE_SHIFT) / sizeof(HARDWARE_PTE_X86);
-
- /* Get the Startup Page Directory */
- PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
-
- /* Set up the Low Memory PDE */
- PageDir->Pde[LowMemPageTableIndex].Valid = 1;
- PageDir->Pde[LowMemPageTableIndex].Write = 1;
- PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
-
- /* Set up the Kernel PDEs */
- PageDir->Pde[KernelPageTableIndex].Valid = 1;
- PageDir->Pde[KernelPageTableIndex].Write = 1;
- PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
- PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
- PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
- PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
-
- /* Set up the Startup PDE */
- PageDir->Pde[StartupPageTableIndex].Valid = 1;
- PageDir->Pde[StartupPageTableIndex].Write = 1;
- PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
-
- /* Set up the Hyperspace PDE */
- PageDir->Pde[HyperspacePageTableIndex].Valid = 1;
- PageDir->Pde[HyperspacePageTableIndex].Write = 1;
- PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable);
-
- /* Set up the Apic PDE */
- PageDir->Pde[ApicPageTableIndex].Valid = 1;
- PageDir->Pde[ApicPageTableIndex].Write = 1;
- PageDir->Pde[ApicPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
-
- /* Set up the KPCR PDE */
- PageDir->Pde[KpcrPageTableIndex].Valid = 1;
- PageDir->Pde[KpcrPageTableIndex].Write = 1;
- PageDir->Pde[KpcrPageTableIndex].PageFrameNumber = PaPtrToPfn(kpcr_pagetable);
-
- /* Set up Low Memory PTEs */
- PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
- for (i=0; i<1024; i++) {
-
- PageDir->Pde[i].Valid = 1;
- PageDir->Pde[i].Write = 1;
- PageDir->Pde[i].Owner = 1;
- PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
- }
-
- /* Set up Kernel PTEs */
- PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
- for (i=0; i<1536; i++) {
-
- PageDir->Pde[i].Valid = 1;
- PageDir->Pde[i].Write = 1;
- PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
- }
-
- /* Set up APIC PTEs */
- PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
- PageDir->Pde[0].Valid = 1;
- PageDir->Pde[0].Write = 1;
- PageDir->Pde[0].CacheDisable = 1;
- PageDir->Pde[0].WriteThrough = 1;
- PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
- PageDir->Pde[0x200].Valid = 1;
- PageDir->Pde[0x200].Write = 1;
- PageDir->Pde[0x200].CacheDisable = 1;
- PageDir->Pde[0x200].WriteThrough = 1;
- PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
-
- /* Set up KPCR PTEs */
- PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable;
- PageDir->Pde[0].Valid = 1;
- PageDir->Pde[0].Write = 1;
- PageDir->Pde[0].PageFrameNumber = 1;
- }
- return;
-#endif
}
/*++
- * FrLdrMapKernel
+ * 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, shsize, shnum, relsize, SectionAddr = 0;
+ PCHAR sptr;
+ Elf32_Ehdr ehdr;
+ Elf32_Shdr *shdr;
+ LPSTR TempName;
+
+ TempName = strrchr(ImageName, '\\');
+ if(TempName) TempName++; else TempName = (LPSTR)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 (!FsReadFile(KernelImage, sizeof(ehdr), NULL, &ehdr)) {
+
+ /* 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)MmAllocateMemory(shnum * shsize);
+
+ /* Read section headers */
+ FsSetFilePointer(KernelImage, ehdr.e_shoff);
+ FsReadFile(KernelImage, shsize * shnum, NULL, sptr);
+
+ printf("Loaded section headers\n");
+
+ /* 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)
+ {
+ FsSetFilePointer(KernelImage, shdr->sh_offset);
+ FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr);
+ ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
+ NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
+ 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);
+ break;
+ }
+ }
+
+ if(i == shnum)
+ {
+ printf("No peheader section encountered :-(\n");
+ return 0;
+ }
+
+ /* Save the Image Base */
+ NtHeader->OptionalHeader.ImageBase = SWAPD(KernelAddr);
+
+ /* Load the file image */
+ Section = COFF_FIRST_SECTION(NtHeader);
+ SectionCount = SWAPW(NtHeader->FileHeader.NumberOfSections);
+
+ printf("Section headers at %x\n", Section);
+
+ /* 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);
+ FsSetFilePointer(KernelImage, shdr->sh_offset);
+ FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr + SectionAddr);
+ }
+ 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);
+ KernelEntry = SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint);
+ printf("Total image size is %x\n", ImageSize);
+
+ /* Handle relocation sections */
+ for (i = 0; i < shnum; i++) {
+ Elf32_Rela reloc = { };
+ ULONG *Target32, x;
+ 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 = MmAllocateMemory(shdr->sh_size);
+ FsSetFilePointer(KernelImage, relstart);
+ FsReadFile(KernelImage, shdr->sh_size, NULL, RelocSection);
+
+ /* Get the symbol section */
+ shdr = ELF_SECTION(shdr->sh_link);
+
+ SymbolSection = MmAllocateMemory(shdr->sh_size);
+ FsSetFilePointer(KernelImage, shdr->sh_offset);
+ FsReadFile(KernelImage, shdr->sh_size, NULL, SymbolSection);
+
+ 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;
+ x = *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
+ }
+
+ MmFreeMemory(SymbolSection);
+ MmFreeMemory(RelocSection);
+ }
+
+ MmFreeMemory(sptr);
+
+ 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, initalizes the
@@ -381,207 +610,63 @@ BOOLEAN
NTAPI
FrLdrMapKernel(FILE *KernelImage)
{
-#if 0
- PIMAGE_DOS_HEADER ImageHeader;
- PIMAGE_NT_HEADERS NtHeader;
- PIMAGE_SECTION_HEADER Section;
- ULONG SectionCount;
- ULONG ImageSize;
- ULONG_PTR SourceSection;
- ULONG_PTR TargetSection;
- ULONG SectionSize;
- LONG i;
- PIMAGE_DATA_DIRECTORY RelocationDDir;
- PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
- ULONG Count;
- ULONG_PTR Address, MaxAddress;
- PUSHORT TypeOffset;
- ULONG_PTR Delta;
- PUSHORT ShortPtr;
- PULONG LongPtr;
-
- /* Allocate 1024 bytes for PE Header */
- ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
-
- /* Make sure it was succesful */
- if (ImageHeader == NULL) {
-
- return FALSE;
- }
-
- /* Load the first 1024 bytes of the kernel image so we can read the PE header */
- if (!FsReadFile(KernelImage, 1024, NULL, ImageHeader)) {
-
- /* Fail if we couldn't read */
- MmFreeMemory(ImageHeader);
- return FALSE;
- }
-
- /* Now read the MZ header to get the offset to the PE Header */
- NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
-
/* Get Kernel Base */
- KernelBase = NtHeader->OptionalHeader.ImageBase;
FrLdrGetKernelBase();
-
- /* Save Entrypoint */
- KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
-
- /* Save the Image Size */
- ImageSize = NtHeader->OptionalHeader.SizeOfImage;
-
- /* Free the Header */
- MmFreeMemory(ImageHeader);
- /* Set the file pointer to zero */
- FsSetFilePointer(KernelImage, 0);
+ /* Allocate kernel memory */
+ KernelMemory = MmAllocateMemory(KernelMemorySize);
+ printf("Kernel Memory @%x\n", (int)KernelMemory);
- /* Load the file image */
- FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS);
-
- /* Reload the NT Header */
- NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew);
-
- /* Load the first section */
- Section = IMAGE_FIRST_SECTION(NtHeader);
- SectionCount = NtHeader->FileHeader.NumberOfSections - 1;
-
- /* Now go to the last section */
- Section += SectionCount;
-
- /* Walk each section backwards */
- for (i=SectionCount; i >= 0; i--, Section--) {
-
- /* Get the disk location and the memory location, and the size */
- SourceSection = RaToPa(Section->PointerToRawData);
- TargetSection = RaToPa(Section->VirtualAddress);
- SectionSize = Section->SizeOfRawData;
-
- /* If the section is already mapped correctly, go to the next */
- if (SourceSection == TargetSection) continue;
-
- /* Load it into memory */
- memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize);
-
- /* Check for unitilizated data */
- if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
-
- /* Zero it out */
- memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData),
- 0,
- Section->Misc.VirtualSize - Section->SizeOfRawData);
- }
- }
-
- /* Get the Relocation Data Directory */
- RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-
- /* Get the Relocation Section Start and End*/
- RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
- RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
-
- /* Calculate Difference between Real Base and Compiled Base*/
- Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
-
- /* Determine how far we shoudl relocate */
- MaxAddress = KERNEL_BASE_PHYS + ImageSize;
-
- /* Relocate until we've processed all the blocks */
- while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
-
- /* See how many Relocation Blocks we have */
- Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
-
- /* Calculate the Address of this Directory */
- Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
-
- /* Calculate the Offset of the Type */
- TypeOffset = (PUSHORT)(RelocationDir + 1);
-
- for (i = 0; i < Count; i++) {
-
- ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
-
- /* Don't relocate after the end of the loaded driver */
- if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
-
- switch (*TypeOffset >> 12) {
-
- case IMAGE_REL_BASED_ABSOLUTE:
- break;
-
- case IMAGE_REL_BASED_HIGH:
- *ShortPtr += HIWORD(Delta);
- break;
-
- case IMAGE_REL_BASED_LOW:
- *ShortPtr += LOWORD(Delta);
- break;
-
- case IMAGE_REL_BASED_HIGHLOW:
- LongPtr = (PULONG)ShortPtr;
- *LongPtr += Delta;
- break;
- }
-
- TypeOffset++;
- }
-
- /* Move to the next Relocation Table */
- RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
- }
-
- /* Increase the next Load Base */
- NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
-
- /* Return Success */
-#endif
- return TRUE;
+ return FrLdrMapModule(KernelImage, "ntoskrnl.exe", KernelMemory, KernelBase);
}
ULONG_PTR
NTAPI
-FrLdrLoadModule(FILE *ModuleImage,
- LPCSTR ModuleName,
+FrLdrLoadModule(FILE *ModuleImage,
+ LPCSTR ModuleName,
PULONG ModuleSize)
{
-#if 0
ULONG LocalModuleSize;
- PFRLDR_MODULE ModuleData;
+ PLOADER_MODULE ModuleData;
LPSTR NameBuffer;
LPSTR TempName;
/* Get current module data structure and module name string array */
- ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
-
+ ModuleData = &reactos_modules[LoaderBlock.ModsCount];
+
/* Get only the Module Name */
do {
-
+
TempName = strchr(ModuleName, '\\');
-
+
if(TempName) {
ModuleName = TempName + 1;
}
} while(TempName);
- NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
+ NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Get Module Size */
LocalModuleSize = FsGetFileSize(ModuleImage);
-
+
/* Fill out Module Data Structure */
- ModuleData->ModuleStart = NextModuleBase;
- ModuleData->ModuleEnd = NextModuleBase + LocalModuleSize;
-
+ ModuleData->ModStart = NextModuleBase;
+ ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
+
+ printf("Module size %x len %x name %s\n",
+ ModuleData->ModStart,
+ ModuleData->ModEnd - ModuleData->ModStart,
+ ModuleName);
+
/* Save name */
strcpy(NameBuffer, ModuleName);
- ModuleData->ModuleName = NameBuffer;
+ ModuleData->String = (ULONG_PTR)NameBuffer;
/* Load the file image */
FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
/* Move to next memory block and increase Module Count */
- NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
+ NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Return Module Size if required */
@@ -589,63 +674,55 @@ FrLdrLoadModule(FILE *ModuleImage,
*ModuleSize = LocalModuleSize;
}
- return(ModuleData->ModuleStart);
-#else
- return 0;
-#endif
+ return(ModuleData->ModStart);
}
ULONG_PTR
NTAPI
FrLdrCreateModule(LPCSTR ModuleName)
{
-#if 0
- PFRLDR_MODULE ModuleData;
+ PLOADER_MODULE ModuleData;
LPSTR NameBuffer;
/* Get current module data structure and module name string array */
- ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
- NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
+ ModuleData = &reactos_modules[LoaderBlock.ModsCount];
+ NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Set up the structure */
- ModuleData->ModuleStart = NextModuleBase;
- ModuleData->ModuleEnd = -1;
-
+ ModuleData->ModStart = NextModuleBase;
+ ModuleData->ModEnd = -1;
+
/* Copy the name */
strcpy(NameBuffer, ModuleName);
- ModuleData->ModuleName = NameBuffer;
+ ModuleData->String = (ULONG_PTR)NameBuffer;
/* Set the current Module */
CurrentModule = ModuleData;
/* Return Module Base Address */
- return(ModuleData->ModuleStart);
-#else
- return 0;
-#endif
+ return(ModuleData->ModStart);
}
BOOLEAN
NTAPI
-FrLdrCloseModule(ULONG_PTR ModuleBase,
+FrLdrCloseModule(ULONG_PTR ModuleBase,
ULONG ModuleSize)
{
-#if 0
- PFRLDR_MODULE ModuleData = CurrentModule;
+ 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->ModuleStart) && (ModuleData->ModuleEnd == -1)) {
-
+ if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) {
+
/* Close the Module */
- ModuleData->ModuleEnd = ModuleData->ModuleStart + ModuleSize;
+ ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
/* Set the next Module Base and increase the number of modules */
- NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
+ NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
-
+
/* Close the currently opened module */
CurrentModule = NULL;
@@ -655,6 +732,5 @@ FrLdrCloseModule(ULONG_PTR ModuleBase,
}
/* Failure path */
-#endif
return(FALSE);
}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c
new file mode 100644
index 00000000000..18676a2a9ea
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c
@@ -0,0 +1,398 @@
+#include
+#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, 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;
+ }
+}
+
+/* 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;
+}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/ofw_util.s b/reactos/boot/freeldr/freeldr/arch/powerpc/ofw_util.s
new file mode 100644
index 00000000000..df921547ee8
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/ofw_util.s
@@ -0,0 +1,49 @@
+ .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
+
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c
new file mode 100644
index 00000000000..b3fe7d56ae9
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c
@@ -0,0 +1,112 @@
+#include "freeldr.h"
+#include "machine.h"
+#include "ppcmmu/mmu.h"
+#include "prep.h"
+
+int prep_serial = 0x800003f8;
+
+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 PpcPrepVideoPrepareForReactOS()
+{
+ pci_setup(&pci1_desc);
+}
+
+int mmu_initialized = 0;
+
+ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
+ ULONG MaxMemoryMapSize )
+{
+ // xxx fixme
+ BiosMemoryMap[0].Type = 1;
+ BiosMemoryMap[0].BaseAddress = 0xe80000;
+ BiosMemoryMap[0].Length = (64 * 1024 * 1024) - BiosMemoryMap[0].BaseAddress;
+ if(!mmu_initialized)
+ {
+ MmuInit();
+ mmu_initialized = 1;
+ }
+ MmuSetMemorySize(BiosMemoryMap[0].Length + BiosMemoryMap[0].BaseAddress);
+ return 1;
+}
+
+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.VideoPrepareForReactOS = PpcPrepVideoPrepareForReactOS;
+
+ MachVtbl.GetMemoryMap = PpcPrepGetMemoryMap;
+
+ printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
+
+ BootMain( "" );
+}
+
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h
new file mode 100644
index 00000000000..ce2cfbff75d
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h
@@ -0,0 +1,24 @@
+#ifndef FREELDR_ARCH_POWERPC_PREP_H
+#define FREELDR_ARCH_POWERPC_PREP_H
+
+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 PpcPrepInit();
+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( 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( struct _pci_desc *pci_desc, struct _vga_desc *vga_desc,
+ int bus, int dev, int fn );
+
+#endif//FREELDR_ARCH_POWERPC_PREP_H
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep_ide.c b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_ide.c
new file mode 100644
index 00000000000..abfcf753313
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_ide.c
@@ -0,0 +1,106 @@
+#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);
+}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c
new file mode 100644
index 00000000000..6254723f25b
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c
@@ -0,0 +1,127 @@
+#include
+#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( 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(desc,&vga1_desc,bus,dev,fn);
+ printf("Done with vga\n");
+ }
+ }
+ }
+ }
+ printf("^-- end PCI\n");
+}
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c
new file mode 100644
index 00000000000..24d8368e245
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c
@@ -0,0 +1,30 @@
+#include
+#include "prep.h"
+#include "ppcboot.h"
+
+extern boot_infos_t BootInfo;
+
+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( 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;
+ }
+ }
+}
diff --git a/reactos/boot/freeldr/freeldr/freeldr.rbuild b/reactos/boot/freeldr/freeldr/freeldr.rbuild
index a4102685021..025ab5c7c6a 100644
--- a/reactos/boot/freeldr/freeldr/freeldr.rbuild
+++ b/reactos/boot/freeldr/freeldr/freeldr.rbuild
@@ -1,12 +1,26 @@
-
-
- freeldr_startup
- freeldr_base64k
- freeldr_base
- freeldr_arch
- freeldr_main
- rossym
- cmlib
- rtl
- libcntpr
-
+
+
+
+ freeldr_startup
+ freeldr_base64k
+ freeldr_base
+ freeldr_arch
+ freeldr_main
+ rossym
+ cmlib
+ rtl
+ libcntpr
+
+
+
+
+ freeldr_startup
+ freeldr_base64k
+ freeldr_base
+ freeldr_arch
+ freeldr_main
+ rossym
+ cmlib
+ rtl
+
+
diff --git a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
index 310680e56ff..6f55745e3c6 100644
--- a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
+++ b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
@@ -47,6 +47,8 @@
include
cache
include
+ include/reactos/libs
+ include/reactos/elf
-ffreestanding
diff --git a/reactos/boot/freeldr/freeldr/fs/fat.c b/reactos/boot/freeldr/freeldr/fs/fat.c
index 14cf1d4ab98..1fbcb2d257c 100644
--- a/reactos/boot/freeldr/freeldr/fs/fat.c
+++ b/reactos/boot/freeldr/freeldr/fs/fat.c
@@ -18,6 +18,8 @@
*/
#include
+
+#define NDEBUG
#include
ULONG BytesPerSector; /* Number of bytes per sector */
@@ -35,6 +37,84 @@ ULONG DataSectorStart; /* Starting sector of the data area */
ULONG FatType = 0; /* FAT12, FAT16, FAT32, FATX16 or FATX32 */
ULONG FatDriveNumber = 0;
+VOID FatSwapFatBootSector(PFAT_BOOTSECTOR Obj)
+{
+ SW(Obj, BytesPerSector);
+ SW(Obj, ReservedSectors);
+ SW(Obj, RootDirEntries);
+ SW(Obj, TotalSectors);
+ SW(Obj, SectorsPerFat);
+ SW(Obj, SectorsPerTrack);
+ SW(Obj, NumberOfHeads);
+ SD(Obj, HiddenSectors);
+ SD(Obj, TotalSectorsBig);
+ SD(Obj, VolumeSerialNumber);
+ SW(Obj, BootSectorMagic);
+}
+
+VOID FatSwapFat32BootSector(PFAT32_BOOTSECTOR Obj)
+{
+ SW(Obj, BytesPerSector);
+ SW(Obj, ReservedSectors);
+ SW(Obj, RootDirEntries);
+ SW(Obj, TotalSectors);
+ SW(Obj, SectorsPerFat);
+ SW(Obj, NumberOfHeads);
+ SD(Obj, HiddenSectors);
+ SD(Obj, TotalSectorsBig);
+ SD(Obj, SectorsPerFatBig);
+ SW(Obj, ExtendedFlags);
+ SW(Obj, FileSystemVersion);
+ SD(Obj, RootDirStartCluster);
+ SW(Obj, FsInfo);
+ SW(Obj, BackupBootSector);
+ SD(Obj, VolumeSerialNumber);
+ SW(Obj, BootSectorMagic);
+}
+
+VOID FatSwapFatXBootSector(PFATX_BOOTSECTOR Obj)
+{
+ SD(Obj, VolumeSerialNumber);
+ SD(Obj, SectorsPerCluster);
+ SW(Obj, NumberOfFats);
+}
+
+VOID FatSwapDirEntry(PDIRENTRY Obj)
+{
+ SW(Obj, CreateTime);
+ SW(Obj, CreateDate);
+ SW(Obj, LastAccessDate);
+ SW(Obj, ClusterHigh);
+ SW(Obj, Time);
+ SW(Obj, Date);
+ SW(Obj, ClusterLow);
+ SD(Obj, Size);
+}
+
+VOID FatSwapLFNDirEntry(PLFN_DIRENTRY Obj)
+{
+ int i;
+ SW(Obj, StartCluster);
+ for(i = 0; i < 5; i++)
+ Obj->Name0_4[i] = SWAPW(Obj->Name0_4[i]);
+ for(i = 0; i < 6; i++)
+ Obj->Name5_10[i] = SWAPW(Obj->Name5_10[i]);
+ for(i = 0; i < 2; i++)
+ Obj->Name11_12[i] = SWAPW(Obj->Name11_12[i]);
+}
+
+VOID FatSwapFatXDirEntry(PFATX_DIRENTRY Obj)
+{
+ SD(Obj, StartCluster);
+ SD(Obj, Size);
+ SW(Obj, Time);
+ SW(Obj, Date);
+ SW(Obj, CreateTime);
+ SW(Obj, CreateDate);
+ SW(Obj, LastAccessTime);
+ SW(Obj, LastAccessDate);
+}
+
BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG PartitionSectorCount)
{
char ErrMsg[80];
@@ -73,13 +153,17 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
}
RtlCopyMemory(FatVolumeBootSector, (PVOID)DISKREADBUFFER, 512);
+
// Get the FAT type
FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount);
+#ifdef DEBUG
+
DbgPrint((DPRINT_FILESYSTEM, "Dumping boot sector:\n"));
if (ISFATX(FatType))
{
+ FatSwapFatXBootSector(FatXVolumeBootSector);
DbgPrint((DPRINT_FILESYSTEM, "sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR)));
DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]));
@@ -93,6 +177,7 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
}
else if (FatType == FAT32)
{
+ FatSwapFat32BootSector(Fat32VolumeBootSector);
DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR)));
DbgPrint((DPRINT_FILESYSTEM, "JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]));
@@ -126,6 +211,7 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
}
else
{
+ FatSwapFatBootSector(FatVolumeBootSector);
DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR)));
DbgPrint((DPRINT_FILESYSTEM, "JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]));
@@ -151,7 +237,9 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
DbgPrint((DPRINT_FILESYSTEM, "BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic));
}
- //
+#endif // defined DEBUG
+
+ //
// Set the correct partition offset
//
FatVolumeStartSector = VolumeStartSector;
@@ -199,7 +287,7 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
if (ISFATX(FatType))
{
BytesPerSector = 512;
- SectorsPerCluster = FatXVolumeBootSector->SectorsPerCluster;
+ SectorsPerCluster = SWAPD(FatXVolumeBootSector->SectorsPerCluster);
FatSectorStart = (4096 / BytesPerSector);
ActiveFatSectorStart = FatSectorStart;
NumberOfFats = 1;
@@ -254,6 +342,7 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
//
// Initialize the disk cache for this drive
//
+ printf("About to do cache init\n");
if (!CacheInitializeDrive(DriveNumber))
{
return FALSE;
@@ -301,10 +390,10 @@ ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONG PartitionSectorCo
}
else
{
- RootDirSectors = ((FatBootSector->RootDirEntries * 32) + (FatBootSector->BytesPerSector - 1)) / FatBootSector->BytesPerSector;
- SectorsPerFat = FatBootSector->SectorsPerFat ? FatBootSector->SectorsPerFat : Fat32BootSector->SectorsPerFatBig;
- TotalSectors = FatBootSector->TotalSectors ? FatBootSector->TotalSectors : FatBootSector->TotalSectorsBig;
- DataSectorCount = TotalSectors - (FatBootSector->ReservedSectors + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);
+ RootDirSectors = ((SWAPW(FatBootSector->RootDirEntries) * 32) + (SWAPW(FatBootSector->BytesPerSector) - 1)) / SWAPW(FatBootSector->BytesPerSector);
+ SectorsPerFat = SWAPW(FatBootSector->SectorsPerFat) ? SWAPW(FatBootSector->SectorsPerFat) : SWAPD(Fat32BootSector->SectorsPerFatBig);
+ TotalSectors = SWAPW(FatBootSector->TotalSectors) ? SWAPW(FatBootSector->TotalSectors) : SWAPD(FatBootSector->TotalSectorsBig);
+ DataSectorCount = TotalSectors - (SWAPW(FatBootSector->ReservedSectors) + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);
//mjl
if (FatBootSector->SectorsPerCluster == 0)
@@ -396,11 +485,13 @@ BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi
{
ULONG EntryCount;
ULONG CurrentEntry;
- PDIRENTRY DirEntry;
- PLFN_DIRENTRY LfnDirEntry;
CHAR LfnNameBuffer[265];
CHAR ShortNameBuffer[20];
ULONG StartCluster;
+ DIRENTRY OurDirEntry;
+ LFN_DIRENTRY OurLfnDirEntry;
+ PDIRENTRY DirEntry = &OurDirEntry;
+ PLFN_DIRENTRY LfnDirEntry = &OurLfnDirEntry;
EntryCount = DirectorySize / sizeof(DIRENTRY);
@@ -409,10 +500,12 @@ BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi
memset(ShortNameBuffer, 0, 13 * sizeof(CHAR));
memset(LfnNameBuffer, 0, 261 * sizeof(CHAR));
- DirEntry = (PDIRENTRY) DirectoryBuffer;
- for (CurrentEntry=0; CurrentEntryFileName[0] == '\0')
{
- return FALSE;
+ return FALSE;
}
//
@@ -607,17 +700,20 @@ static BOOLEAN FatXSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG Dir
{
ULONG EntryCount;
ULONG CurrentEntry;
- PFATX_DIRENTRY DirEntry;
ULONG FileNameLen;
+ FATX_DIRENTRY OurDirEntry;
+ PFATX_DIRENTRY DirEntry = &OurDirEntry;
EntryCount = DirectorySize / sizeof(FATX_DIRENTRY);
DbgPrint((DPRINT_FILESYSTEM, "FatXSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName));
FileNameLen = strlen(FileName);
- DirEntry = (PFATX_DIRENTRY) DirectoryBuffer;
- for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirEntry++)
+
+ for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirectoryBuffer = ((PFATX_DIRENTRY)DirectoryBuffer)+1)
{
+ OurDirEntry = *(PFATX_DIRENTRY) DirectoryBuffer;
+ FatSwapFatXDirEntry(&OurDirEntry);
if (0xff == DirEntry->FileNameSize)
{
break;
@@ -715,6 +811,7 @@ BOOLEAN FatLookupFile(PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
// Buffer the directory contents
//
DirectoryBuffer = FatBufferDirectory(DirectoryStartCluster, &DirectorySize, (i == 0) );
+
if (DirectoryBuffer == NULL)
{
return FALSE;
@@ -848,6 +945,7 @@ BOOLEAN FatGetFatEntry(ULONG Cluster, ULONG* ClusterPointer)
}
fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset));
+ fat = SWAPW(fat);
if (Cluster & 0x0001)
fat = fat >> 4; /* Cluster number is ODD */
else
@@ -868,6 +966,7 @@ BOOLEAN FatGetFatEntry(ULONG Cluster, ULONG* ClusterPointer)
}
fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset));
+ fat = SWAPW(fat);
break;
@@ -885,6 +984,7 @@ BOOLEAN FatGetFatEntry(ULONG Cluster, ULONG* ClusterPointer)
// Get the fat entry
fat = (*((ULONG *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset))) & 0x0FFFFFFF;
+ fat = SWAPD(fat);
break;
diff --git a/reactos/boot/freeldr/freeldr/fs/fs.c b/reactos/boot/freeldr/freeldr/fs/fs.c
index a6654380043..f7116b9bca0 100644
--- a/reactos/boot/freeldr/freeldr/fs/fs.c
+++ b/reactos/boot/freeldr/freeldr/fs/fs.c
@@ -18,6 +18,8 @@
*/
#include
+
+#define NDEBUG
#include
/////////////////////////////////////////////////////////////////////////////////////////////
@@ -25,6 +27,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////
ULONG FsType = 0; // Type of filesystem on boot device, set by FsOpenVolume()
+PVOID FsStaticBufferDisk = 0, FsStaticBufferData = 0;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
@@ -49,8 +52,20 @@ static BOOLEAN FsOpenVolume(ULONG DriveNumber, ULONGLONG StartSector, ULONGLONG
{
CHAR ErrorText[80];
+ printf("FsOpenVolume: (disk=%d,start=%d,count=%d,type=%d)\n",
+ DriveNumber, StartSector, SectorCount, Type);
+
FsType = Type;
+ if( !FsStaticBufferDisk )
+ FsStaticBufferDisk = MmAllocateMemory( 0x20000 );
+ if( !FsStaticBufferDisk )
+ {
+ FileSystemError("could not allocate filesystem static buffer");
+ return FALSE;
+ }
+ FsStaticBufferData = ((PCHAR)FsStaticBufferDisk) + 0x10000;
+
switch (FsType)
{
case FS_FAT:
@@ -150,6 +165,7 @@ PFILE FsOpenFile(PCSTR FileName)
break;
}
+#ifdef DEBUG
//
// Check return value
//
@@ -161,6 +177,7 @@ PFILE FsOpenFile(PCSTR FileName)
{
DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() failed.\n"));
}
+#endif // defined DEBUG
return FileHandle;
}
diff --git a/reactos/boot/freeldr/freeldr/fs/fsrec.c b/reactos/boot/freeldr/freeldr/fs/fsrec.c
index b34187780f8..32a73549a4b 100644
--- a/reactos/boot/freeldr/freeldr/fs/fsrec.c
+++ b/reactos/boot/freeldr/freeldr/fs/fsrec.c
@@ -18,6 +18,8 @@
*/
#include
+
+#define NDEBUG
#include
/////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/reactos/boot/freeldr/freeldr/include/bytesex.h b/reactos/boot/freeldr/freeldr/include/bytesex.h
new file mode 100644
index 00000000000..ccbfc7cad05
--- /dev/null
+++ b/reactos/boot/freeldr/freeldr/include/bytesex.h
@@ -0,0 +1,14 @@
+#ifndef __BYTESEX_H_
+#define __BYTESEX_H_
+
+#ifdef _PPC_
+#define SWAPD(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
+#define SWAPW(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
+#else
+#define SWAPD(x) x
+#define SWAPW(x) x
+#endif
+#define SD(Object,Field) Object->Field = SWAPD(Object->Field)
+#define SW(Object,Field) Object->Field = SWAPW(Object->Field)
+
+#endif/*__BYTESEX_H_*/
diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h
index 57f307adfe5..b8a335379fd 100644
--- a/reactos/boot/freeldr/freeldr/include/freeldr.h
+++ b/reactos/boot/freeldr/freeldr/include/freeldr.h
@@ -87,6 +87,8 @@
#include
/* Needed if debuging is enabled */
#include
+/* Swap */
+#include
#define Ke386EraseFlags(x) __asm__ __volatile__("pushl $0 ; popfl\n")
diff --git a/reactos/boot/freeldr/freeldr/include/of.h b/reactos/boot/freeldr/freeldr/include/of.h
index 445f6654dfe..2f623d5f9a5 100644
--- a/reactos/boot/freeldr/freeldr/include/of.h
+++ b/reactos/boot/freeldr/freeldr/include/of.h
@@ -4,23 +4,14 @@
#define OF_FAILED 0
#define ERR_NOT_FOUND 0xc0000010
-#define REV(x) (((x)>>24)&0xff)|(((x)>>8)&0xff00)|(((x)<<24)&0xff000000)|(((x)<<8)&0xff0000)
+#include "of_call.h"
+#include
typedef int (*of_proxy)
- ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4 );
+ ( 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 ofw_finddevice( const char *name );
-int ofw_getprop( int package, const char *name, void *buffer, int size );
-int ofw_open( const char *name );
-int ofw_write( int handle, const char *buffer, int size );
-int ofw_read( int handle, const char *buffer, int size );
-void ofw_print_string(const char *);
-void ofw_print_number(int);
-void ofw_exit();
-
int setjmp( jmp_buf buf );
int longjmp( jmp_buf buf, int retval );
diff --git a/reactos/boot/freeldr/freeldr/mm/mm.c b/reactos/boot/freeldr/freeldr/mm/mm.c
index b510f9a251c..2d0371dec91 100644
--- a/reactos/boot/freeldr/freeldr/mm/mm.c
+++ b/reactos/boot/freeldr/freeldr/mm/mm.c
@@ -19,6 +19,9 @@
#include
#include
+#ifdef _M_PPC
+#include "of.h"
+#endif
ULONG AllocationCount = 0;
@@ -65,6 +68,12 @@ PVOID MmAllocateMemory(ULONG MemorySize)
if (MemorySize == 0)
{
+#ifdef _M_PPC
+ ULONG ptr;
+ printf("Allocating %d bytes directly ...\n", MemorySize);
+ ptr = ofw_claim(0,MemorySize,MM_PAGE_SIZE);
+ MemPointer = (PVOID)(ptr);
+#endif
DbgPrint((DPRINT_MEMORY, "MmAllocateMemory() called for 0 bytes. Returning NULL.\n"));
UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
return NULL;
diff --git a/reactos/hal/hal.rbuild b/reactos/hal/hal.rbuild
index 552e3306f9a..ea9ce8db0b5 100644
--- a/reactos/hal/hal.rbuild
+++ b/reactos/hal/hal.rbuild
@@ -2,7 +2,14 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/reactos/hal/hal/hal.rbuild b/reactos/hal/hal/hal.rbuild
index ded2af3c3a8..bc0e94ab53b 100644
--- a/reactos/hal/hal/hal.rbuild
+++ b/reactos/hal/hal/hal.rbuild
@@ -9,8 +9,13 @@
hal.rc
-
-
+
+
+
-
-
+
+
+
+
+
+
diff --git a/reactos/hal/halppc/generic/beep.c b/reactos/hal/halppc/generic/beep.c
new file mode 100644
index 00000000000..f4e9d3b07ea
--- /dev/null
+++ b/reactos/hal/halppc/generic/beep.c
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/beep.c
+ * PURPOSE: Speaker function (it's only one)
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 31/01/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+
+/* 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
+STDCALL
+HalMakeBeep (
+ ULONG Frequency
+ )
+{
+ return TRUE;
+}
+
diff --git a/reactos/hal/halppc/generic/bus.c b/reactos/hal/halppc/generic/bus.c
new file mode 100644
index 00000000000..a35adbe315a
--- /dev/null
+++ b/reactos/hal/halppc/generic/bus.c
@@ -0,0 +1,356 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/bus.c
+ * PURPOSE: Bus Support Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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) && (NextBus == TRUE)) 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 */
+ KEBUGCHECK(0);
+ }
+ 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 */
diff --git a/reactos/hal/halppc/generic/cmos.c b/reactos/hal/halppc/generic/cmos.c
new file mode 100644
index 00000000000..14cd589b0e5
--- /dev/null
+++ b/reactos/hal/halppc/generic/cmos.c
@@ -0,0 +1,291 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/cmos.c
+ * PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood)
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 */
diff --git a/reactos/hal/halppc/generic/display.c b/reactos/hal/halppc/generic/display.c
new file mode 100644
index 00000000000..4e0d8edd6b7
--- /dev/null
+++ b/reactos/hal/halppc/generic/display.c
@@ -0,0 +1,385 @@
+/*
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: display.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/display.c
+ * PURPOSE: Blue screen display
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * 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
+#include
+#include
+#include
+
+#define NDEBUG
+#include
+
+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: Initalize 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 STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+ if (HalResetDisplayParameters == NULL)
+ return;
+
+ if (HalOwnsDisplay == TRUE)
+ return;
+
+ HalOwnsDisplay = TRUE;
+ HalClearDisplay(0);
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * ResetDisplayParameters = Pointer to a driver specific
+ * reset routine.
+ */
+{
+ HalOwnsDisplay = FALSE;
+ HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+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 STDCALL
+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 STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+ IN ULONG CursorPosY)
+{
+ CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+ CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+ return !HalOwnsDisplay;
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/dma.c b/reactos/hal/halppc/generic/dma.c
new file mode 100644
index 00000000000..f0d7f0a1000
--- /dev/null
+++ b/reactos/hal/halppc/generic/dma.c
@@ -0,0 +1,2024 @@
+/* $Id: dma.c 24759 2006-11-14 20:59:48Z ion $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/dma.c
+ * PURPOSE: DMA functions
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Filip Navara (navaraf@reactos.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/**
+ * @page DMA Implementation Notes
+ *
+ * Concepts:
+ *
+ * - Map register
+ *
+ * Abstract encapsulation of physically contiguous buffer that resides
+ * in memory accessible by both the DMA device / controller and the system.
+ * The map registers are allocated and distributed on demand and are
+ * scarce resource.
+ *
+ * The actual use of map registers is to allow transfers from/to buffer
+ * located in physical memory at address inaccessible by the DMA device /
+ * controller directly. For such transfers the map register buffers
+ * are used as intermediate data storage.
+ *
+ * - Master adapter
+ *
+ * A container for map registers (typically corresponding to one physical
+ * bus connection type). There can be master adapters for 24-bit address
+ * ranges, 32-bit address ranges, etc. Every time a new DMA adapter is
+ * created it's associated with a corresponding master adapter that
+ * is used for any map register allocation requests.
+ *
+ * - Bus-master / Slave DMA
+ *
+ * Slave DMA is term used for DMA transfers done by the system (E)ISA
+ * controller as opposed to transfers mastered by the device itself
+ * (hence the name).
+ *
+ * For slave DMA special care is taken to actually access the system
+ * controller and handle the transfers. The relevant code is in
+ * HalpDmaInitializeEisaAdapter, HalReadDmaCounter, IoFlushAdapterBuffers
+ * and IoMapTransfer.
+ *
+ * Implementation:
+ *
+ * - Allocation of map registers
+ *
+ * Initial set of map registers is allocated on the system start to
+ * ensure that low memory won't get filled up later. Additional map
+ * registers are allocated as needed by HalpGrowMapBuffers. This
+ * routine is called on two places:
+ *
+ * - HalGetAdapter, since we're at PASSIVE_LEVEL and it's known that
+ * more map registers will probably be needed.
+ * - IoAllocateAdapterChannel (indirectly using HalpGrowMapBufferWorker
+ * since we're at DISPATCH_LEVEL and call HalpGrowMapBuffers directly)
+ * when no more map registers are free.
+ *
+ * Note that even if no more map registers can be allocated it's not
+ * the end of the world. The adapters waiting for free map registers
+ * are queued in the master adapter's queue and once one driver hands
+ * back it's map registers (using IoFreeMapRegisters or indirectly using
+ * the execution routine callback in IoAllocateAdapterChannel) the
+ * queue gets processed and the map registers are reassigned.
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+static KEVENT HalpDmaLock;
+static LIST_ENTRY HalpDmaAdapterList;
+static PADAPTER_OBJECT HalpEisaAdapter[8];
+static BOOLEAN HalpEisaDma;
+static PADAPTER_OBJECT HalpMasterAdapter;
+
+static const ULONG_PTR HalpEisaPortPage[8] = {
+ FIELD_OFFSET(DMA_PAGE, Channel0),
+ FIELD_OFFSET(DMA_PAGE, Channel1),
+ FIELD_OFFSET(DMA_PAGE, Channel2),
+ FIELD_OFFSET(DMA_PAGE, Channel3),
+ 0,
+ FIELD_OFFSET(DMA_PAGE, Channel5),
+ FIELD_OFFSET(DMA_PAGE, Channel6),
+ FIELD_OFFSET(DMA_PAGE, Channel7)
+};
+
+static DMA_OPERATIONS HalpDmaOperations = {
+ sizeof(DMA_OPERATIONS),
+ (PPUT_DMA_ADAPTER)HalPutDmaAdapter,
+ (PALLOCATE_COMMON_BUFFER)HalAllocateCommonBuffer,
+ (PFREE_COMMON_BUFFER)HalFreeCommonBuffer,
+ NULL, /* Initialized in HalpInitDma() */
+ NULL, /* Initialized in HalpInitDma() */
+ NULL, /* Initialized in HalpInitDma() */
+ NULL, /* Initialized in HalpInitDma() */
+ NULL, /* Initialized in HalpInitDma() */
+ (PGET_DMA_ALIGNMENT)HalpDmaGetDmaAlignment,
+ (PREAD_DMA_COUNTER)HalReadDmaCounter,
+ /* FIXME: Implement the S/G funtions. */
+ NULL /*(PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList*/,
+ NULL /*(PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList*/,
+ NULL /*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize*/,
+ NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/,
+ NULL /*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*/
+};
+
+#define MAX_MAP_REGISTERS 64
+
+#define TAG_DMA TAG('D','M','A',' ')
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+HalpInitDma(VOID)
+{
+ /*
+ * Initialize the DMA Operation table
+ */
+ HalpDmaOperations.AllocateAdapterChannel = (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel;
+ HalpDmaOperations.FlushAdapterBuffers = (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers;
+ HalpDmaOperations.FreeAdapterChannel = (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel;
+ HalpDmaOperations.FreeMapRegisters = (PFREE_MAP_REGISTERS)IoFreeMapRegisters;
+ HalpDmaOperations.MapTransfer = (PMAP_TRANSFER)IoMapTransfer;
+
+ /*
+ * Check if Extended DMA is available. We're just going to do a random
+ * read and write.
+ */
+
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A);
+ if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A)
+ HalpEisaDma = TRUE;
+
+ /*
+ * Intialize all the global variables and allocate master adapter with
+ * first map buffers.
+ */
+
+ InitializeListHead(&HalpDmaAdapterList);
+ KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE);
+
+ HalpMasterAdapter = HalpDmaAllocateMasterAdapter();
+
+ /*
+ * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
+ * used by IoGetDmaAdapter in the kernel.
+ */
+
+ HalGetDmaAdapter = HalpGetDmaAdapter;
+}
+
+/**
+ * @name HalpGetAdapterMaximumPhysicalAddress
+ *
+ * Get the maximum physical address acceptable by the device represented
+ * by the passed DMA adapter.
+ */
+
+PHYSICAL_ADDRESS STDCALL
+HalpGetAdapterMaximumPhysicalAddress(
+ IN PADAPTER_OBJECT AdapterObject)
+{
+ PHYSICAL_ADDRESS HighestAddress;
+
+ if (AdapterObject->MasterDevice)
+ {
+ if (AdapterObject->Dma64BitAddresses)
+ {
+ HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
+ return HighestAddress;
+ }
+ else if (AdapterObject->Dma32BitAddresses)
+ {
+ HighestAddress.QuadPart = 0xFFFFFFFF;
+ return HighestAddress;
+ }
+ }
+
+ HighestAddress.QuadPart = 0xFFFFFF;
+ return HighestAddress;
+}
+
+/**
+ * @name HalpGrowMapBuffers
+ *
+ * Allocate initial, or additional, map buffers for DMA master adapter.
+ *
+ * @param MasterAdapter
+ * DMA master adapter to allocate buffers for.
+ * @param SizeOfMapBuffers
+ * Size of the map buffers to allocate (not including the size
+ * already allocated).
+ */
+
+BOOLEAN STDCALL
+HalpGrowMapBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG SizeOfMapBuffers)
+{
+ PVOID VirtualAddress;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PHYSICAL_ADDRESS HighestAcceptableAddress;
+ PHYSICAL_ADDRESS LowestAcceptableAddress;
+ PHYSICAL_ADDRESS BoundryAddressMultiple;
+ KIRQL OldIrql;
+ ULONG MapRegisterCount;
+
+ /* FIXME: Check if enough map register slots are available. */
+
+ MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
+
+ /*
+ * Allocate memory for the new map registers. For 32-bit adapters we use
+ * two passes in order not to waste scare resource (low memory).
+ */
+
+ HighestAcceptableAddress =
+ HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
+ LowestAcceptableAddress.HighPart = 0;
+ LowestAcceptableAddress.LowPart =
+ HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
+ BoundryAddressMultiple.QuadPart = 0;
+
+ VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
+ MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
+ HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
+
+ if (VirtualAddress == NULL && LowestAcceptableAddress.LowPart != 0)
+ {
+ LowestAcceptableAddress.LowPart = 0;
+ VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
+ MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
+ HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
+ }
+
+ if (VirtualAddress == NULL)
+ return FALSE;
+
+ PhysicalAddress = MmGetPhysicalAddress(VirtualAddress);
+
+ /*
+ * All the following must be done with the master adapter lock held
+ * to prevent corruption.
+ */
+
+ OldIrql = KfAcquireSpinLock(&AdapterObject->SpinLock);
+
+ /*
+ * Setup map register entries for the buffer allocated. Each entry has
+ * a virtual and physical address and corresponds to PAGE_SIZE large
+ * buffer.
+ */
+
+ if (MapRegisterCount > 0)
+ {
+ PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
+
+ CurrentEntry = AdapterObject->MapRegisterBase +
+ AdapterObject->NumberOfMapRegisters;
+ do
+ {
+ /*
+ * Leave one entry free for every non-contiguous memory region
+ * in the map register bitmap. This ensures that we can search
+ * using RtlFindClearBits for contiguous map register regions.
+ *
+ * Also for non-EISA DMA leave one free entry for every 64Kb
+ * break, because the DMA controller can handle only coniguous
+ * 64Kb regions.
+ */
+
+ if (CurrentEntry != AdapterObject->MapRegisterBase)
+ {
+ PreviousEntry = CurrentEntry - 1;
+ if (PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE ==
+ PhysicalAddress.LowPart)
+ {
+ if (!HalpEisaDma)
+ {
+ if ((PreviousEntry->PhysicalAddress.LowPart ^
+ PhysicalAddress.LowPart) & 0xFFFF0000)
+ {
+ CurrentEntry++;
+ AdapterObject->NumberOfMapRegisters++;
+ }
+ }
+ }
+ else
+ {
+ CurrentEntry++;
+ AdapterObject->NumberOfMapRegisters++;
+ }
+ }
+
+ RtlClearBit(AdapterObject->MapRegisters,
+ CurrentEntry - AdapterObject->MapRegisterBase);
+ CurrentEntry->VirtualAddress = VirtualAddress;
+ CurrentEntry->PhysicalAddress = PhysicalAddress;
+
+ PhysicalAddress.LowPart += PAGE_SIZE;
+ VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
+
+ CurrentEntry++;
+ AdapterObject->NumberOfMapRegisters++;
+ MapRegisterCount--;
+ }
+ while (MapRegisterCount != 0);
+ }
+
+ KfReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
+
+ return TRUE;
+}
+
+/**
+ * @name HalpDmaAllocateMasterAdapter
+ *
+ * Helper routine to allocate and initialize master adapter object and it's
+ * associated map register buffers.
+ *
+ * @see HalpInitDma
+ */
+
+PADAPTER_OBJECT STDCALL
+HalpDmaAllocateMasterAdapter(VOID)
+{
+ PADAPTER_OBJECT MasterAdapter;
+ ULONG Size, SizeOfBitmap;
+
+ SizeOfBitmap = MAX_MAP_REGISTERS;
+ Size = sizeof(ADAPTER_OBJECT);
+ Size += sizeof(RTL_BITMAP);
+ Size += (SizeOfBitmap + 7) >> 3;
+
+ MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA);
+ if (MasterAdapter == NULL)
+ return NULL;
+
+ RtlZeroMemory(MasterAdapter, Size);
+
+ KeInitializeSpinLock(&MasterAdapter->SpinLock);
+ InitializeListHead(&MasterAdapter->AdapterQueue);
+
+ MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
+ RtlInitializeBitMap(
+ MasterAdapter->MapRegisters,
+ (PULONG)(MasterAdapter->MapRegisters + 1),
+ SizeOfBitmap);
+ RtlSetAllBits(MasterAdapter->MapRegisters);
+ MasterAdapter->NumberOfMapRegisters = 0;
+ MasterAdapter->CommittedMapRegisters = 0;
+
+ MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(
+ NonPagedPool,
+ SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY),
+ TAG_DMA);
+ if (MasterAdapter->MapRegisterBase == NULL)
+ {
+ ExFreePool(MasterAdapter);
+ return NULL;
+ }
+
+ RtlZeroMemory(MasterAdapter->MapRegisterBase,
+ SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
+ if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
+ {
+ ExFreePool(MasterAdapter);
+ return NULL;
+ }
+
+ return MasterAdapter;
+}
+
+/**
+ * @name HalpDmaAllocateChildAdapter
+ *
+ * Helper routine of HalGetAdapter. Allocate child adapter object and
+ * fill out some basic fields.
+ *
+ * @see HalGetAdapter
+ */
+
+PADAPTER_OBJECT STDCALL
+HalpDmaAllocateChildAdapter(
+ ULONG NumberOfMapRegisters,
+ PDEVICE_DESCRIPTION DeviceDescription)
+{
+ PADAPTER_OBJECT AdapterObject;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ HANDLE Handle;
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ NULL,
+ OBJ_KERNEL_HANDLE | OBJ_PERMANENT,
+ NULL,
+ NULL);
+
+ Status = ObCreateObject(
+ KernelMode,
+ IoAdapterObjectType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ sizeof(ADAPTER_OBJECT),
+ 0,
+ 0,
+ (PVOID)&AdapterObject);
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ Status = ObReferenceObjectByPointer(
+ AdapterObject,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ IoAdapterObjectType,
+ KernelMode);
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
+
+ Status = ObInsertObject(
+ AdapterObject,
+ NULL,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ &Handle);
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ ZwClose(Handle);
+
+ AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
+ AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
+ AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
+ AdapterObject->MapRegistersPerChannel = 1;
+ AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+ AdapterObject->ChannelNumber = 0xFF;
+ AdapterObject->MasterAdapter = HalpMasterAdapter;
+ KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
+
+ return AdapterObject;
+}
+
+/**
+ * @name HalpDmaInitializeEisaAdapter
+ *
+ * Setup DMA modes and extended modes for (E)ISA DMA adapter object.
+ */
+
+BOOLEAN STDCALL
+HalpDmaInitializeEisaAdapter(
+ PADAPTER_OBJECT AdapterObject,
+ PDEVICE_DESCRIPTION DeviceDescription)
+{
+ UCHAR Controller;
+ DMA_MODE DmaMode = {{0 }};
+ DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
+ PVOID AdapterBaseVa;
+
+ Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
+
+ if (Controller == 1)
+ AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
+ else
+ AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
+
+ AdapterObject->AdapterNumber = Controller;
+ AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
+ AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
+ AdapterObject->Width16Bits = FALSE;
+ AdapterObject->AdapterBaseVa = AdapterBaseVa;
+
+ if (HalpEisaDma)
+ {
+ ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
+
+ switch (DeviceDescription->DmaSpeed)
+ {
+ case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
+ case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
+ case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
+ case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
+ default:
+ return FALSE;
+ }
+
+ switch (DeviceDescription->DmaWidth)
+ {
+ case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
+ case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
+ case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
+ default:
+ return FALSE;
+ }
+
+ if (Controller == 1)
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
+ ExtendedMode.Byte);
+ else
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
+ ExtendedMode.Byte);
+ }
+ else
+ {
+ /*
+ * Validate setup for non-busmaster DMA adapter. Secondary controller
+ * supports only 16-bit transfers and main controller supports only
+ * 8-bit transfers. Anything else is invalid.
+ */
+
+ if (!DeviceDescription->Master)
+ {
+ if (Controller == 2 && DeviceDescription->DmaWidth == Width16Bits)
+ AdapterObject->Width16Bits = TRUE;
+ else if (Controller != 1 || DeviceDescription->DmaWidth != Width8Bits)
+ return FALSE;
+ }
+ }
+
+ DmaMode.Channel = AdapterObject->ChannelNumber;
+ DmaMode.AutoInitialize = DeviceDescription->AutoInitialize;
+
+ /*
+ * Set the DMA request mode.
+ *
+ * For (E)ISA bus master devices just unmask (enable) the DMA channel
+ * and set it to cascade mode. Otherwise just select the right one
+ * bases on the passed device description.
+ */
+
+ if (DeviceDescription->Master)
+ {
+ DmaMode.RequestMode = CASCADE_REQUEST_MODE;
+ if (Controller == 1)
+ {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode,
+ DmaMode.Byte);
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ } else {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode,
+ DmaMode.Byte);
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+ }
+ else
+ {
+ if (DeviceDescription->DemandMode)
+ DmaMode.RequestMode = DEMAND_REQUEST_MODE;
+ else
+ DmaMode.RequestMode = SINGLE_REQUEST_MODE;
+ }
+
+ AdapterObject->AdapterMode = DmaMode;
+
+ return TRUE;
+}
+
+/**
+ * @name HalGetAdapter
+ *
+ * Allocate an adapter object for DMA device.
+ *
+ * @param DeviceDescription
+ * Structure describing the attributes of the device.
+ * @param NumberOfMapRegisters
+ * On return filled with the maximum number of map registers the
+ * device driver can allocate for DMA transfer operations.
+ *
+ * @return The DMA adapter on success, NULL otherwise.
+ *
+ * @implemented
+ */
+
+PADAPTER_OBJECT STDCALL
+HalGetAdapter(
+ PDEVICE_DESCRIPTION DeviceDescription,
+ PULONG NumberOfMapRegisters)
+{
+ PADAPTER_OBJECT AdapterObject = NULL;
+ PADAPTER_OBJECT MasterAdapter;
+ BOOLEAN EisaAdapter;
+ ULONG MapRegisters;
+ ULONG MaximumLength;
+
+ /* Validate parameters in device description */
+ if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION2)
+ return NULL;
+
+ /*
+ * See if we're going to use ISA/EISA DMA adapter. These adapters are
+ * special since they're reused.
+ *
+ * Also note that we check for channel number since there are only 8 DMA
+ * channels on ISA, so any request above this requires new adapter.
+ */
+
+ if (DeviceDescription->InterfaceType == Isa || !DeviceDescription->Master)
+ {
+ if (DeviceDescription->InterfaceType == Isa &&
+ DeviceDescription->DmaChannel >= 8)
+ EisaAdapter = FALSE;
+ else
+ EisaAdapter = TRUE;
+ }
+ else
+ {
+ EisaAdapter = FALSE;
+ }
+
+ /*
+ * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
+ * for cascading the controllers and it's not available for software use.
+ */
+
+ if (EisaAdapter && DeviceDescription->DmaChannel == 4)
+ return NULL;
+
+ /*
+ * Calculate the number of map registers.
+ *
+ * - For EISA and PCI scatter/gather no map registers are needed.
+ * - For ISA slave scatter/gather one map register is needed.
+ * - For all other cases the number of map registers depends on
+ * DeviceDescription->MaximumLength.
+ */
+
+ MaximumLength = DeviceDescription->MaximumLength & MAXLONG;
+ if (DeviceDescription->ScatterGather &&
+ (DeviceDescription->InterfaceType == Eisa ||
+ DeviceDescription->InterfaceType == PCIBus))
+ {
+ MapRegisters = 0;
+ }
+ else if (DeviceDescription->ScatterGather &&
+ !DeviceDescription->Master)
+ {
+ MapRegisters = 1;
+ }
+ else
+ {
+ /*
+ * In the equation below the additional map register added by
+ * the "+1" accounts for the case when a transfer does not start
+ * at a page-aligned address.
+ */
+ MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
+ if (MapRegisters > 16)
+ MapRegisters = 16;
+ }
+
+ /*
+ * Acquire the DMA lock that is used to protect adapter lists and
+ * EISA adapter array.
+ */
+
+ KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
+ FALSE, NULL);
+
+ /*
+ * Now we must get ahold of the adapter object. For first eight ISA/EISA
+ * channels there are static adapter objects that are reused and updated
+ * on succesive HalGetAdapter calls. In other cases a new adapter object
+ * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
+ */
+
+ if (EisaAdapter)
+ {
+ AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
+ if (AdapterObject != NULL)
+ {
+ if (AdapterObject->NeedsMapRegisters &&
+ MapRegisters > AdapterObject->MapRegistersPerChannel)
+ AdapterObject->MapRegistersPerChannel = MapRegisters;
+ }
+ }
+
+ if (AdapterObject == NULL)
+ {
+ AdapterObject = HalpDmaAllocateChildAdapter(
+ MapRegisters, DeviceDescription);
+ if (AdapterObject == NULL)
+ {
+ KeSetEvent(&HalpDmaLock, 0, 0);
+ return NULL;
+ }
+
+ if (EisaAdapter)
+ {
+ HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
+ }
+
+ if (MapRegisters > 0)
+ {
+ AdapterObject->NeedsMapRegisters = TRUE;
+ MasterAdapter = HalpMasterAdapter;
+ AdapterObject->MapRegistersPerChannel = MapRegisters;
+
+ /*
+ * FIXME: Verify that the following makes sense. Actually
+ * MasterAdapter->NumberOfMapRegisters contains even the number
+ * of gaps, so this will not work correctly all the time. It
+ * doesn't matter much since it's only optimization to avoid
+ * queuing work items in HalAllocateAdapterChannel.
+ */
+
+ MasterAdapter->CommittedMapRegisters += MapRegisters;
+ if (MasterAdapter->CommittedMapRegisters > MasterAdapter->NumberOfMapRegisters)
+ HalpGrowMapBuffers(MasterAdapter, 0x10000);
+ }
+ else
+ {
+ AdapterObject->NeedsMapRegisters = FALSE;
+ if (DeviceDescription->Master)
+ AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
+ else
+ AdapterObject->MapRegistersPerChannel = 1;
+ }
+ }
+
+ if (!EisaAdapter)
+ InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
+
+ /*
+ * Release the DMA lock. HalpDmaAdapterList and HalpEisaAdapter will
+ * no longer be touched, so we don't need it.
+ */
+
+ KeSetEvent(&HalpDmaLock, 0, 0);
+
+ /*
+ * Setup the values in the adapter object that are common for all
+ * types of buses.
+ */
+
+ if (DeviceDescription->Version >= DEVICE_DESCRIPTION_VERSION1)
+ AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
+ else
+ AdapterObject->IgnoreCount = 0;
+
+ AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+ AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
+ AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
+ AdapterObject->MasterDevice = DeviceDescription->Master;
+ *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
+
+ /*
+ * For non-(E)ISA adapters we have already done all the work. On the
+ * other hand for (E)ISA adapters we must still setup the DMA modes
+ * and prepare the controller.
+ */
+
+ if (EisaAdapter)
+ {
+ if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription))
+ {
+ ObfDereferenceObject(AdapterObject);
+ return NULL;
+ }
+ }
+
+ return AdapterObject;
+}
+
+/**
+ * @name HalpGetDmaAdapter
+ *
+ * Internal routine to allocate PnP DMA adapter object. It's exported through
+ * HalDispatchTable and used by IoGetDmaAdapter.
+ *
+ * @see HalGetAdapter
+ */
+
+PDMA_ADAPTER STDCALL
+HalpGetDmaAdapter(
+ IN PVOID Context,
+ IN PDEVICE_DESCRIPTION DeviceDescription,
+ OUT PULONG NumberOfMapRegisters)
+{
+ return &HalGetAdapter(DeviceDescription, NumberOfMapRegisters)->DmaHeader;
+}
+
+/**
+ * @name HalPutDmaAdapter
+ *
+ * Internal routine to free DMA adapter and resources for reuse. It's exported
+ * using the DMA_OPERATIONS interface by HalGetAdapter.
+ *
+ * @see HalGetAdapter
+ */
+
+VOID STDCALL
+HalPutDmaAdapter(
+ PADAPTER_OBJECT AdapterObject)
+{
+ if (AdapterObject->ChannelNumber == 0xFF)
+ {
+ KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
+ FALSE, NULL);
+ RemoveEntryList(&AdapterObject->AdapterList);
+ KeSetEvent(&HalpDmaLock, 0, 0);
+ }
+
+ ObfDereferenceObject(AdapterObject);
+}
+
+/**
+ * @name HalAllocateCommonBuffer
+ *
+ * Allocates memory that is visible to both the processor(s) and the DMA
+ * device.
+ *
+ * @param AdapterObject
+ * Adapter object representing the bus master or system dma controller.
+ * @param Length
+ * Number of bytes to allocate.
+ * @param LogicalAddress
+ * Logical address the driver can use to access the buffer.
+ * @param CacheEnabled
+ * Specifies if the memory can be cached.
+ *
+ * @return The base virtual address of the memory allocated or NULL on failure.
+ *
+ * @remarks
+ * On real NT x86 systems the CacheEnabled parameter is ignored, we honour
+ * it. If it proves to cause problems change it.
+ *
+ * @see HalFreeCommonBuffer
+ *
+ * @implemented
+ */
+
+PVOID STDCALL
+HalAllocateCommonBuffer(
+ PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PPHYSICAL_ADDRESS LogicalAddress,
+ BOOLEAN CacheEnabled)
+{
+ PHYSICAL_ADDRESS LowestAcceptableAddress;
+ PHYSICAL_ADDRESS HighestAcceptableAddress;
+ PHYSICAL_ADDRESS BoundryAddressMultiple;
+ PVOID VirtualAddress;
+
+ LowestAcceptableAddress.QuadPart = 0;
+ HighestAcceptableAddress =
+ HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
+ BoundryAddressMultiple.QuadPart = 0;
+
+ /*
+ * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
+ * slave DMA devices the 64Kb boundary mustn't be crossed since the
+ * controller wouldn't be able to handle it.
+ */
+
+ if (AdapterObject->MasterDevice)
+ BoundryAddressMultiple.HighPart = 1;
+ else
+ BoundryAddressMultiple.LowPart = 0x10000;
+
+ VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
+ Length, LowestAcceptableAddress, HighestAcceptableAddress,
+ BoundryAddressMultiple, CacheEnabled ? MmCached : MmNonCached);
+ if (VirtualAddress == NULL)
+ return NULL;
+
+ *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
+
+ return VirtualAddress;
+}
+
+/**
+ * @name HalFreeCommonBuffer
+ *
+ * Free common buffer allocated with HalAllocateCommonBuffer.
+ *
+ * @see HalAllocateCommonBuffer
+ *
+ * @implemented
+ */
+
+VOID STDCALL
+HalFreeCommonBuffer(
+ PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PHYSICAL_ADDRESS LogicalAddress,
+ PVOID VirtualAddress,
+ BOOLEAN CacheEnabled)
+{
+ MmFreeContiguousMemory(VirtualAddress);
+}
+
+/**
+ * @name HalpDmaGetDmaAlignment
+ *
+ * Internal routine to return the DMA alignment requirement. It's exported
+ * using the DMA_OPERATIONS interface by HalGetAdapter.
+ *
+ * @see HalGetAdapter
+ */
+
+ULONG STDCALL
+HalpDmaGetDmaAlignment(
+ PADAPTER_OBJECT AdapterObject)
+{
+ return 1;
+}
+
+/*
+ * @name HalReadDmaCounter
+ *
+ * Read DMA operation progress counter.
+ *
+ * @implemented
+ */
+
+ULONG STDCALL
+HalReadDmaCounter(
+ PADAPTER_OBJECT AdapterObject)
+{
+ KIRQL OldIrql;
+ ULONG Count, OldCount;
+
+ ASSERT(!AdapterObject->MasterDevice);
+
+ /*
+ * Acquire the master adapter lock since we're going to mess with the
+ * system DMA controller registers and we really don't want anyone
+ * to do the same at the same time.
+ */
+
+ KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
+
+ /* Send the request to the specific controller. */
+ if (AdapterObject->AdapterNumber == 1)
+ {
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ Count = 0xffff00;
+ do
+ {
+ OldCount = Count;
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+ }
+ while (0xffff00 & (OldCount ^ Count));
+ }
+ else
+ {
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ Count = 0xffff00;
+ do
+ {
+ OldCount = Count;
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+ }
+ while (0xffff00 & (OldCount ^ Count));
+ }
+
+ KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
+
+ Count++;
+ Count &= 0xffff;
+ if (AdapterObject->Width16Bits)
+ Count *= 2;
+
+ return Count;
+}
+
+/**
+ * @name HalpGrowMapBufferWorker
+ *
+ * Helper routine of HalAllocateAdapterChannel for allocating map registers
+ * at PASSIVE_LEVEL in work item.
+ */
+
+VOID STDCALL
+HalpGrowMapBufferWorker(PVOID DeferredContext)
+{
+ PGROW_WORK_ITEM WorkItem = (PGROW_WORK_ITEM)DeferredContext;
+ KIRQL OldIrql;
+ BOOLEAN Succeeded;
+
+ /*
+ * Try to allocate new map registers for the adapter.
+ *
+ * NOTE: The NT implementation actually tries to allocate more map
+ * registers than needed as an optimization.
+ */
+
+ KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
+ FALSE, NULL);
+ Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
+ WorkItem->NumberOfMapRegisters);
+ KeSetEvent(&HalpDmaLock, 0, 0);
+
+ if (Succeeded)
+ {
+ /*
+ * Flush the adapter queue now that new map registers are ready. The
+ * easiest way to do that is to call IoFreeMapRegisters to not free
+ * any registers. Note that we use the magic (PVOID)2 map register
+ * base to bypass the parameter checking.
+ */
+
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
+ KeLowerIrql(OldIrql);
+ }
+
+ ExFreePool(WorkItem);
+}
+
+/**
+ * @name HalAllocateAdapterChannel
+ *
+ * Setup map registers for an adapter object.
+ *
+ * @param AdapterObject
+ * Pointer to an ADAPTER_OBJECT to set up.
+ * @param WaitContextBlock
+ * Context block to be used with ExecutionRoutine.
+ * @param NumberOfMapRegisters
+ * Number of map registers requested.
+ * @param ExecutionRoutine
+ * Callback to call when map registers are allocated.
+ *
+ * @return
+ * If not enough map registers can be allocated then
+ * STATUS_INSUFFICIENT_RESOURCES is returned. If the function
+ * succeeds or the callback is queued for later delivering then
+ * STATUS_SUCCESS is returned.
+ *
+ * @see IoFreeAdapterChannel
+ *
+ * @implemented
+ */
+
+NTSTATUS STDCALL
+HalAllocateAdapterChannel(
+ PADAPTER_OBJECT AdapterObject,
+ PWAIT_CONTEXT_BLOCK WaitContextBlock,
+ ULONG NumberOfMapRegisters,
+ PDRIVER_CONTROL ExecutionRoutine)
+{
+ PADAPTER_OBJECT MasterAdapter;
+ PGROW_WORK_ITEM WorkItem;
+ ULONG Index = ~0;
+ ULONG Result;
+ KIRQL OldIrql;
+
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Set up the wait context block in case we can't run right away. */
+ WaitContextBlock->DeviceRoutine = ExecutionRoutine;
+ WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
+
+ /* Returns true if queued, else returns false and sets the queue to busy */
+ if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
+ return STATUS_SUCCESS;
+
+ MasterAdapter = AdapterObject->MasterAdapter;
+
+ AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
+ AdapterObject->CurrentWcb = WaitContextBlock;
+
+ if (NumberOfMapRegisters && AdapterObject->NeedsMapRegisters)
+ {
+ if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
+ {
+ AdapterObject->NumberOfMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /*
+ * Get the map registers. This is partly complicated by the fact
+ * that new map registers can only be allocated at PASSIVE_LEVEL
+ * and we're currently at DISPATCH_LEVEL. The following code has
+ * two code paths:
+ *
+ * - If there is no adapter queued for map register allocation,
+ * try to see if enough contiguous map registers are present.
+ * In case they're we can just get them and proceed further.
+ *
+ * - If some adapter is already present in the queue we must
+ * respect the order of adapters asking for map registers and
+ * so the fast case described above can't take place.
+ * This case is also entered if not enough coniguous map
+ * registers are present.
+ *
+ * A work queue item is allocated and queued, the adapter is
+ * also queued into the master adapter queue. The worker
+ * routine does the job of allocating the map registers at
+ * PASSIVE_LEVEL and calling the ExecutionRoutine.
+ */
+
+ OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
+
+ if (IsListEmpty(&MasterAdapter->AdapterQueue))
+ {
+ Index = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
+ if (Index != ~0)
+ {
+ AdapterObject->MapRegisterBase =
+ MasterAdapter->MapRegisterBase + Index;
+ if (!AdapterObject->ScatterGather)
+ {
+ AdapterObject->MapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)(
+ (ULONG_PTR)AdapterObject->MapRegisterBase |
+ MAP_BASE_SW_SG);
+ }
+ }
+ }
+
+ if (Index == ~0)
+ {
+ WorkItem = ExAllocatePoolWithTag(
+ NonPagedPool, sizeof(GROW_WORK_ITEM), TAG_DMA);
+ if (WorkItem == NULL)
+ {
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+ AdapterObject->NumberOfMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
+
+ ExInitializeWorkItem(
+ &WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem);
+ WorkItem->AdapterObject = AdapterObject;
+ WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
+
+ ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
+
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+
+ return STATUS_SUCCESS;
+ }
+
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+ }
+ else
+ {
+ AdapterObject->MapRegisterBase = NULL;
+ AdapterObject->NumberOfMapRegisters = 0;
+ }
+
+ AdapterObject->CurrentWcb = WaitContextBlock;
+
+ Result = ExecutionRoutine(
+ WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ /*
+ * Possible return values:
+ *
+ * - KeepObject
+ * Don't free any resources, the ADAPTER_OBJECT is still in use and
+ * the caller will call IoFreeAdapterChannel later.
+ *
+ * - DeallocateObject
+ * Deallocate the map registers and release the ADAPTER_OBJECT, so
+ * someone else can use it.
+ *
+ * - DeallocateObjectKeepRegisters
+ * Release the ADAPTER_OBJECT, but hang on to the map registers. The
+ * client will later call IoFreeMapRegisters.
+ *
+ * NOTE:
+ * IoFreeAdapterChannel runs the queue, so it must be called unless
+ * the adapter object is not to be freed.
+ */
+
+ if (Result == DeallocateObject)
+ {
+ IoFreeAdapterChannel(AdapterObject);
+ }
+ else if (Result == DeallocateObjectKeepRegisters)
+ {
+ AdapterObject->NumberOfMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+/**
+ * @name IoFreeAdapterChannel
+ *
+ * Free DMA resources allocated by IoAllocateAdapterChannel.
+ *
+ * @param AdapterObject
+ * Adapter object with resources to free.
+ *
+ * @remarks
+ * This function releases map registers registers assigned to the DMA
+ * adapter. After releasing the adapter, it checks the adapter's queue
+ * and runs each queued device object in series until the queue is
+ * empty. This is the only way the device queue is emptied.
+ *
+ * @see IoAllocateAdapterChannel
+ *
+ * @implemented
+ */
+
+VOID STDCALL
+IoFreeAdapterChannel(
+ PADAPTER_OBJECT AdapterObject)
+{
+ PADAPTER_OBJECT MasterAdapter;
+ PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
+ PWAIT_CONTEXT_BLOCK WaitContextBlock;
+ ULONG Index = ~0;
+ ULONG Result;
+ KIRQL OldIrql;
+
+ MasterAdapter = AdapterObject->MasterAdapter;
+
+ for (;;)
+ {
+ /*
+ * To keep map registers, call here with AdapterObject->
+ * NumberOfMapRegisters set to zero. This trick is used in
+ * HalAllocateAdapterChannel for example.
+ */
+ if (AdapterObject->NumberOfMapRegisters)
+ {
+ IoFreeMapRegisters(
+ AdapterObject,
+ AdapterObject->MapRegisterBase,
+ AdapterObject->NumberOfMapRegisters);
+ }
+
+ DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
+ if (DeviceQueueEntry == NULL)
+ {
+ break;
+ }
+
+ WaitContextBlock = CONTAINING_RECORD(
+ DeviceQueueEntry,
+ WAIT_CONTEXT_BLOCK,
+ WaitQueueEntry);
+
+ AdapterObject->CurrentWcb = WaitContextBlock;
+ AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
+
+ if (WaitContextBlock->NumberOfMapRegisters &&
+ AdapterObject->MasterAdapter)
+ {
+ OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
+
+ if (IsListEmpty(&MasterAdapter->AdapterQueue))
+ {
+ Index = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ WaitContextBlock->NumberOfMapRegisters, 0);
+ if (Index != ~0)
+ {
+ AdapterObject->MapRegisterBase =
+ MasterAdapter->MapRegisterBase + Index;
+ if (!AdapterObject->ScatterGather)
+ {
+ AdapterObject->MapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)(
+ (ULONG_PTR)AdapterObject->MapRegisterBase |
+ MAP_BASE_SW_SG);
+ }
+ }
+ }
+
+ if (Index == ~0)
+ {
+ InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+ break;
+ }
+
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+ }
+ else
+ {
+ AdapterObject->MapRegisterBase = NULL;
+ AdapterObject->NumberOfMapRegisters = 0;
+ }
+
+ /* Call the adapter control routine. */
+ Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(
+ WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ switch (Result)
+ {
+ case KeepObject:
+ /*
+ * We're done until the caller manually calls IoFreeAdapterChannel
+ * or IoFreeMapRegisters.
+ */
+ return;
+
+ case DeallocateObjectKeepRegisters:
+ /*
+ * Hide the map registers so they aren't deallocated next time
+ * around.
+ */
+ AdapterObject->NumberOfMapRegisters = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * @name IoFreeMapRegisters
+ *
+ * Free map registers reserved by the system for a DMA.
+ *
+ * @param AdapterObject
+ * DMA adapter to free map registers on.
+ * @param MapRegisterBase
+ * Handle to map registers to free.
+ * @param NumberOfRegisters
+ * Number of map registers to be freed.
+ *
+ * @implemented
+ */
+
+VOID STDCALL
+IoFreeMapRegisters(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PVOID MapRegisterBase,
+ IN ULONG NumberOfMapRegisters)
+{
+ PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
+ PLIST_ENTRY ListEntry;
+ KIRQL OldIrql;
+ ULONG Index;
+ ULONG Result;
+
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ if (MasterAdapter == NULL || MapRegisterBase == NULL)
+ return;
+
+ OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
+
+ if (NumberOfMapRegisters != 0)
+ {
+ PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
+
+ RealMapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
+ RtlClearBits(MasterAdapter->MapRegisters,
+ RealMapRegisterBase - MasterAdapter->MapRegisterBase,
+ NumberOfMapRegisters);
+ }
+
+ /*
+ * Now that we freed few map registers it's time to look at the master
+ * adapter queue and see if there is someone waiting for map registers.
+ */
+
+ while (!IsListEmpty(&MasterAdapter->AdapterQueue))
+ {
+ ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
+ AdapterObject = CONTAINING_RECORD(
+ ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
+
+ Index = RtlFindClearBitsAndSet(
+ MasterAdapter->MapRegisters,
+ AdapterObject->NumberOfMapRegisters,
+ MasterAdapter->NumberOfMapRegisters);
+ if (Index == ~0)
+ {
+ InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
+ break;
+ }
+
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+
+ AdapterObject->MapRegisterBase =
+ MasterAdapter->MapRegisterBase + Index;
+ if (!AdapterObject->ScatterGather)
+ {
+ AdapterObject->MapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)(
+ (ULONG_PTR)AdapterObject->MapRegisterBase |
+ MAP_BASE_SW_SG);
+ }
+
+ Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(
+ AdapterObject->CurrentWcb->DeviceObject,
+ AdapterObject->CurrentWcb->CurrentIrp,
+ AdapterObject->MapRegisterBase,
+ AdapterObject->CurrentWcb->DeviceContext);
+
+ switch (Result)
+ {
+ case DeallocateObjectKeepRegisters:
+ AdapterObject->NumberOfMapRegisters = 0;
+ /* fall through */
+
+ case DeallocateObject:
+ if (AdapterObject->NumberOfMapRegisters)
+ {
+ OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
+ RtlClearBits(MasterAdapter->MapRegisters,
+ AdapterObject->MapRegisterBase -
+ MasterAdapter->MapRegisterBase,
+ AdapterObject->NumberOfMapRegisters);
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+ }
+ IoFreeAdapterChannel(AdapterObject);
+ break;
+
+ default:
+ break;
+ }
+
+ OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
+ }
+
+ KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
+}
+
+/**
+ * @name HalpCopyBufferMap
+ *
+ * Helper function for copying data from/to map register buffers.
+ *
+ * @see IoFlushAdapterBuffers, IoMapTransfer
+ */
+
+VOID STDCALL
+HalpCopyBufferMap(
+ PMDL Mdl,
+ PROS_MAP_REGISTER_ENTRY MapRegisterBase,
+ PVOID CurrentVa,
+ ULONG Length,
+ BOOLEAN WriteToDevice)
+{
+ ULONG CurrentLength;
+ ULONG_PTR CurrentAddress;
+ ULONG ByteOffset;
+ PVOID VirtualAddress;
+
+ VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
+ if (VirtualAddress == NULL)
+ {
+ /*
+ * NOTE: On real NT a mechanism with reserved pages is implemented
+ * to handle this case in a slow, but graceful non-fatal way.
+ */
+ /* FIXME: The correct bug check code isn't defined. */
+ /* KEBUGCHECKEX(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0); */
+ KEBUGCHECK(0);
+ }
+
+ CurrentAddress = (ULONG_PTR)VirtualAddress +
+ (ULONG_PTR)CurrentVa -
+ (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
+
+ while (Length > 0)
+ {
+ ByteOffset = BYTE_OFFSET(CurrentAddress);
+ CurrentLength = PAGE_SIZE - ByteOffset;
+ if (CurrentLength > Length)
+ CurrentLength = Length;
+
+ if (WriteToDevice)
+ {
+ RtlCopyMemory(
+ (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
+ (PVOID)CurrentAddress,
+ CurrentLength);
+ }
+ else
+ {
+ RtlCopyMemory(
+ (PVOID)CurrentAddress,
+ (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
+ CurrentLength);
+ }
+
+ Length -= CurrentLength;
+ CurrentAddress += CurrentLength;
+ MapRegisterBase++;
+ }
+}
+
+/**
+ * @name IoFlushAdapterBuffers
+ *
+ * Flush any data remaining in the DMA controller's memory into the host
+ * memory.
+ *
+ * @param AdapterObject
+ * The adapter object to flush.
+ * @param Mdl
+ * Original MDL to flush data into.
+ * @param MapRegisterBase
+ * Map register base that was just used by IoMapTransfer, etc.
+ * @param CurrentVa
+ * Offset into Mdl to be flushed into, same as was passed to
+ * IoMapTransfer.
+ * @param Length
+ * Length of the buffer to be flushed into.
+ * @param WriteToDevice
+ * TRUE if it's a write, FALSE if it's a read.
+ *
+ * @return TRUE in all cases.
+ *
+ * @remarks
+ * This copies data from the map register-backed buffer to the user's
+ * target buffer. Data are not in the user buffer until this function
+ * is called.
+ * For slave DMA transfers the controller channel is masked effectively
+ * stopping the current transfer.
+ *
+ * @unimplemented.
+ */
+
+BOOLEAN STDCALL
+IoFlushAdapterBuffers(
+ PADAPTER_OBJECT AdapterObject,
+ PMDL Mdl,
+ PVOID MapRegisterBase,
+ PVOID CurrentVa,
+ ULONG Length,
+ BOOLEAN WriteToDevice)
+{
+ BOOLEAN SlaveDma = FALSE;
+ PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
+ PHYSICAL_ADDRESS HighestAcceptableAddress;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PPFN_NUMBER MdlPagesPtr;
+
+ ASSERT_IRQL(DISPATCH_LEVEL);
+
+ if (AdapterObject != NULL && !AdapterObject->MasterDevice)
+ {
+ /* Mask out (disable) the DMA channel. */
+ if (AdapterObject->AdapterNumber == 1)
+ {
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
+ AdapterObject->ChannelNumber | DMA_SETMASK);
+ }
+ else
+ {
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
+ AdapterObject->ChannelNumber | DMA_SETMASK);
+ }
+ SlaveDma = TRUE;
+ }
+
+ /* This can happen if the device supports hardware scatter/gather. */
+ if (MapRegisterBase == NULL)
+ return TRUE;
+
+ RealMapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
+
+ if (!WriteToDevice)
+ {
+ if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
+ {
+ if (RealMapRegisterBase->Counter != ~0)
+ {
+ if (SlaveDma && !AdapterObject->IgnoreCount)
+ Length -= HalReadDmaCounter(AdapterObject);
+ HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
+ }
+ }
+ else
+ {
+ MdlPagesPtr = MmGetMdlPfnArray(Mdl);
+ MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
+
+ PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
+ PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
+
+ HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
+ if (PhysicalAddress.QuadPart + Length >
+ HighestAcceptableAddress.QuadPart)
+ {
+ HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
+ }
+ }
+ }
+
+ RealMapRegisterBase->Counter = 0;
+
+ return TRUE;
+}
+
+/**
+ * @name IoMapTransfer
+ *
+ * Map a DMA for transfer and do the DMA if it's a slave.
+ *
+ * @param AdapterObject
+ * Adapter object to do the DMA on. Bus-master may pass NULL.
+ * @param Mdl
+ * Locked-down user buffer to DMA in to or out of.
+ * @param MapRegisterBase
+ * Handle to map registers to use for this dma.
+ * @param CurrentVa
+ * Index into Mdl to transfer into/out of.
+ * @param Length
+ * Length of transfer. Number of bytes actually transferred on
+ * output.
+ * @param WriteToDevice
+ * TRUE if it's an output DMA, FALSE otherwise.
+ *
+ * @return
+ * A logical address that can be used to program a DMA controller, it's
+ * not meaningful for slave DMA device.
+ *
+ * @remarks
+ * This function does a copyover to contiguous memory <16MB represented
+ * by the map registers if needed. If the buffer described by MDL can be
+ * used as is no copyover is done.
+ * If it's a slave transfer, this function actually performs it.
+ *
+ * @implemented
+ */
+
+PHYSICAL_ADDRESS STDCALL
+IoMapTransfer(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN OUT PULONG Length,
+ IN BOOLEAN WriteToDevice)
+{
+ PPFN_NUMBER MdlPagesPtr;
+ PFN_NUMBER MdlPage1, MdlPage2;
+ ULONG ByteOffset;
+ ULONG TransferOffset;
+ ULONG TransferLength;
+ BOOLEAN UseMapRegisters;
+ PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PHYSICAL_ADDRESS HighestAcceptableAddress;
+ ULONG Counter;
+ DMA_MODE AdapterMode;
+ KIRQL OldIrql;
+
+ /*
+ * Precalculate some values that are used in all cases.
+ *
+ * ByteOffset is offset inside the page at which the transfer starts.
+ * MdlPagesPtr is pointer inside the MDL page chain at the page where the
+ * transfer start.
+ * PhysicalAddress is physical address corresponding to the transfer
+ * start page and offset.
+ * TransferLength is the inital length of the transfer, which is reminder
+ * of the first page. The actual value is calculated below.
+ *
+ * Note that all the variables can change during the processing which
+ * takes place below. These are just initial values.
+ */
+
+ ByteOffset = BYTE_OFFSET(CurrentVa);
+
+ MdlPagesPtr = MmGetMdlPfnArray(Mdl);
+ MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
+
+ PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
+ PhysicalAddress.QuadPart += ByteOffset;
+
+ TransferLength = PAGE_SIZE - ByteOffset;
+
+ /*
+ * Special case for bus master adapters with S/G support. We can directly
+ * use the buffer specified by the MDL, so not much work has to be done.
+ *
+ * Just return the passed VA's corresponding physical address and update
+ * length to the number of physically contiguous bytes found. Also
+ * pages crossing the 4Gb boundary aren't considered physically contiguous.
+ */
+
+ if (MapRegisterBase == NULL)
+ {
+ while (TransferLength < *Length)
+ {
+ MdlPage1 = *MdlPagesPtr;
+ MdlPage2 = *(MdlPagesPtr + 1);
+ if (MdlPage1 + 1 != MdlPage2)
+ break;
+ if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF)
+ break;
+ TransferLength += PAGE_SIZE;
+ MdlPagesPtr++;
+ }
+
+ if (TransferLength < *Length)
+ *Length = TransferLength;
+
+ return PhysicalAddress;
+ }
+
+ /*
+ * The code below applies to slave DMA adapters and bus master adapters
+ * without hardward S/G support.
+ */
+
+ RealMapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
+
+ /*
+ * Try to calculate the size of the transfer. We can only transfer
+ * pages that are physically contiguous and that don't cross the
+ * 64Kb boundary (this limitation applies only for ISA controllers).
+ */
+
+ while (TransferLength < *Length)
+ {
+ MdlPage1 = *MdlPagesPtr;
+ MdlPage2 = *(MdlPagesPtr + 1);
+ if (MdlPage1 + 1 != MdlPage2)
+ break;
+ if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF))
+ break;
+ TransferLength += PAGE_SIZE;
+ MdlPagesPtr++;
+ }
+
+ if (TransferLength > *Length)
+ TransferLength = *Length;
+
+ /*
+ * If we're about to simulate software S/G and not all the pages are
+ * physically contiguous then we must use the map registers to store
+ * the data and allow the whole transfer to proceed at once.
+ */
+
+ if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG &&
+ TransferLength < *Length)
+ {
+ UseMapRegisters = TRUE;
+ PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
+ PhysicalAddress.QuadPart += ByteOffset;
+ TransferLength = *Length;
+ RealMapRegisterBase->Counter = ~0;
+ Counter = 0;
+ }
+ else
+ {
+ /*
+ * This is ordinary DMA transfer, so just update the progress
+ * counters. These are used by IoFlushAdapterBuffers to track
+ * the transfer progress.
+ */
+
+ UseMapRegisters = FALSE;
+ Counter = RealMapRegisterBase->Counter;
+ RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
+
+ /*
+ * Check if the buffer doesn't exceed the highest physical address
+ * limit of the device. In that case we must use the map registers to
+ * store the data.
+ */
+
+ HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
+ if (PhysicalAddress.QuadPart + TransferLength >
+ HighestAcceptableAddress.QuadPart)
+ {
+ UseMapRegisters = TRUE;
+ PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
+ PhysicalAddress.QuadPart += ByteOffset;
+ if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
+ {
+ RealMapRegisterBase->Counter = ~0;
+ Counter = 0;
+ }
+ }
+ }
+
+ /*
+ * If we decided to use the map registers (see above) and we're about
+ * to transfer data to the device then copy the buffers into the map
+ * register memory.
+ */
+
+ if (UseMapRegisters && WriteToDevice)
+ {
+ HalpCopyBufferMap(Mdl, RealMapRegisterBase + Counter,
+ CurrentVa, TransferLength, WriteToDevice);
+ }
+
+ /*
+ * Return the length of transfer that actually takes place.
+ */
+
+ *Length = TransferLength;
+
+ /*
+ * If we're doing slave (system) DMA then program the (E)ISA controller
+ * to actually start the transfer.
+ */
+
+ if (AdapterObject != NULL && !AdapterObject->MasterDevice)
+ {
+ AdapterMode = AdapterObject->AdapterMode;
+
+ if (WriteToDevice)
+ {
+ AdapterMode.TransferType = WRITE_TRANSFER;
+ }
+ else
+ {
+ AdapterMode.TransferType = READ_TRANSFER;
+ if (AdapterObject->IgnoreCount)
+ {
+ RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress +
+ ByteOffset, TransferLength);
+ }
+ }
+
+ TransferOffset = PhysicalAddress.LowPart & 0xFFFF;
+ if (AdapterObject->Width16Bits)
+ {
+ TransferLength >>= 1;
+ TransferOffset >>= 1;
+ }
+
+ OldIrql = KfAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock);
+
+ if (AdapterObject->AdapterNumber == 1)
+ {
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
+ /* Set the Offset Register */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
+ (UCHAR)(TransferOffset));
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
+ (UCHAR)(TransferOffset >> 8));
+ /* Set the Page Register */
+ WRITE_PORT_UCHAR(AdapterObject->PagePort +
+ FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
+ (UCHAR)(PhysicalAddress.LowPart >> 16));
+ if (HalpEisaDma)
+ {
+ WRITE_PORT_UCHAR(AdapterObject->PagePort +
+ FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
+ 0);
+ }
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)(TransferLength - 1));
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((TransferLength - 1) >> 8));
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+ else
+ {
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
+ /* Set the Offset Register */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
+ (UCHAR)(TransferOffset));
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
+ (UCHAR)(TransferOffset >> 8));
+ /* Set the Page Register */
+ WRITE_PORT_UCHAR(AdapterObject->PagePort +
+ FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
+ (UCHAR)(PhysicalAddress.u.LowPart >> 16));
+ if (HalpEisaDma)
+ {
+ WRITE_PORT_UCHAR(AdapterObject->PagePort +
+ FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
+ 0);
+ }
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)(TransferLength - 1));
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((TransferLength - 1) >> 8));
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+
+ KfReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
+ }
+
+ /*
+ * Return physical address of the buffer with data that is used for the
+ * transfer. It can either point inside the Mdl that was passed by the
+ * caller or into the map registers if the Mdl buffer can't be used
+ * directly.
+ */
+
+ return PhysicalAddress;
+}
+
+/**
+ * @name HalFlushCommonBuffer
+ *
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalFlushCommonBuffer(IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG Length,
+ IN PHYSICAL_ADDRESS LogicalAddress,
+ IN PVOID VirtualAddress)
+{
+ /* Function always returns true */
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+PVOID
+NTAPI
+HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject,
+ IN OUT PULONG NumberOfMapRegisters)
+{
+ PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
+ ULONG MapRegisterNumber;
+
+ /* Check if it needs map registers */
+ if (AdapterObject->NeedsMapRegisters)
+ {
+ /* Check if we have enough */
+ if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
+ {
+ /* We don't, fail */
+ AdapterObject->NumberOfMapRegisters = 0;
+ return NULL;
+ }
+
+ /* Try to find free map registers */
+ MapRegisterNumber = -1;
+ MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
+ *NumberOfMapRegisters,
+ 0);
+
+ /* Check if nothing was found */
+ if (MapRegisterNumber == -1)
+ {
+ /* No free registers found, so use the base registers */
+ RtlSetBits(MasterAdapter->MapRegisters,
+ 0,
+ *NumberOfMapRegisters);
+ MapRegisterNumber = 0;
+ }
+
+ /* Calculate the new base */
+ AdapterObject->MapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
+ MapRegisterNumber);
+
+ /* Check if scatter gather isn't supported */
+ if (!AdapterObject->ScatterGather)
+ {
+ /* Set the flag */
+ AdapterObject->MapRegisterBase =
+ (PROS_MAP_REGISTER_ENTRY)
+ ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
+ }
+ }
+ else
+ {
+ AdapterObject->MapRegisterBase = NULL;
+ AdapterObject->NumberOfMapRegisters = 0;
+ }
+
+ /* Return the base */
+ return AdapterObject->MapRegisterBase;
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/drive.c b/reactos/hal/halppc/generic/drive.c
new file mode 100644
index 00000000000..fc489c9c8d6
--- /dev/null
+++ b/reactos/hal/halppc/generic/drive.c
@@ -0,0 +1,74 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/drive.c
+ * PURPOSE: I/O HAL Routines for Disk Access
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 */
diff --git a/reactos/hal/halppc/generic/enum.c b/reactos/hal/halppc/generic/enum.c
new file mode 100644
index 00000000000..af8b06d4a87
--- /dev/null
+++ b/reactos/hal/halppc/generic/enum.c
@@ -0,0 +1,23 @@
+/* $Id: enum.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/enum.c
+ * PURPOSE: Motherboard device enumerator
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 01/05/2001
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+VOID
+HalpStartEnumerator (VOID)
+{
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/fmutex.c b/reactos/hal/halppc/generic/fmutex.c
new file mode 100644
index 00000000000..8ec41f4ce11
--- /dev/null
+++ b/reactos/hal/halppc/generic/fmutex.c
@@ -0,0 +1,100 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS HAL
+ * FILE: ntoskrnl/hal/x86/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
+#define NDEBUG
+#include
+
+#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->Gate,
+ 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->Gate, 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 */
diff --git a/reactos/hal/halppc/generic/font.c b/reactos/hal/halppc/generic/font.c
new file mode 100644
index 00000000000..570cc5f1e51
--- /dev/null
+++ b/reactos/hal/halppc/generic/font.c
@@ -0,0 +1,278 @@
+/* $Id: font.c 21840 2006-05-07 18:56:52Z ion $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Xbox HAL
+ * FILE: hal/halx86/xbox/font.h
+ * 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
+
+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 */
+
diff --git a/reactos/hal/halppc/generic/generic.rbuild b/reactos/hal/halppc/generic/generic.rbuild
new file mode 100644
index 00000000000..dd40b0d6626
--- /dev/null
+++ b/reactos/hal/halppc/generic/generic.rbuild
@@ -0,0 +1,29 @@
+
+ ../include
+ include
+
+
+
+ beep.c
+ bus.c
+ cmos.c
+ display.c
+ dma.c
+ drive.c
+ enum.c
+ fmutex.c
+ font.c
+ halinit.c
+ irql.c
+ isa.c
+ misc.c
+ pci.c
+ portio.c
+ processor.c
+ profil.c
+ reboot.c
+ spinlock.c
+ sysinfo.c
+ timer.c
+ ../include/hal.h
+
diff --git a/reactos/hal/halppc/generic/halinit.c b/reactos/hal/halppc/generic/halinit.c
new file mode 100644
index 00000000000..d7a81adc2cc
--- /dev/null
+++ b/reactos/hal/halppc/generic/halinit.c
@@ -0,0 +1,158 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/halinit.c
+ * PURPOSE: HAL Entrypoint and Initialization
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 */
diff --git a/reactos/hal/halppc/generic/ipi.c b/reactos/hal/halppc/generic/ipi.c
new file mode 100644
index 00000000000..739de8d716c
--- /dev/null
+++ b/reactos/hal/halppc/generic/ipi.c
@@ -0,0 +1,24 @@
+/* $Id: ipi.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/ipi.c
+ * PURPOSE: Miscellaneous hardware functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+ DPRINT("HalRequestIpi(ProcessorNo %lu)\n", ProcessorNo);
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/irql.c b/reactos/hal/halppc/generic/irql.c
new file mode 100644
index 00000000000..ed3ad450a84
--- /dev/null
+++ b/reactos/hal/halppc/generic/irql.c
@@ -0,0 +1,450 @@
+/* $Id$
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/irql.c
+ * PURPOSE: Implements IRQLs
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 STDCALL
+KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
+
+#endif
+
+/* FUNCTIONS ****************************************************************/
+
+#undef KeGetCurrentIrql
+KIRQL STDCALL 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(0);
+ 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 (0);
+ 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 STDCALL
+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 STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+ return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+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 STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+ HalpLowerIrql(Irql);
+ HalpEndSystemInterrupt(Irql);
+}
+
+BOOLEAN
+STDCALL
+HalDisableSystemInterrupt(
+ ULONG Vector,
+ KIRQL Irql)
+{
+ 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.slave));
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+STDCALL
+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:
+ KEBUGCHECK(0);
+ }
+}
+
+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:
+ KEBUGCHECK(0);
+ }
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/isa.c b/reactos/hal/halppc/generic/isa.c
new file mode 100644
index 00000000000..665bb1edd45
--- /dev/null
+++ b/reactos/hal/halppc/generic/isa.c
@@ -0,0 +1,75 @@
+/* $Id: isa.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/isa.c
+ * PURPOSE: Interfaces to the ISA bus
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * 05/06/98: Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 STDCALL
+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 STDCALL
+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 */
diff --git a/reactos/hal/halppc/generic/kdbg.c b/reactos/hal/halppc/generic/kdbg.c
new file mode 100644
index 00000000000..c9e4474fa8a
--- /dev/null
+++ b/reactos/hal/halppc/generic/kdbg.c
@@ -0,0 +1,547 @@
+/* $Id: kdbg.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/kdbg.c
+ * PURPOSE: Serial i/o functions for the kernel debugger.
+ * PROGRAMMER: Emanuele Aliberti
+ * Eric Kohl
+ * UPDATE HISTORY:
+ * Created 05/09/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+
+#define DEFAULT_BAUD_RATE 19200
+
+
+/* MACROS *******************************************************************/
+
+#define SER_RBR(x) ((x)+0)
+#define SER_THR(x) ((x)+0)
+#define SER_DLL(x) ((x)+0)
+#define SER_IER(x) ((x)+1)
+#define SR_IER_ERDA 0x01
+#define SR_IER_ETHRE 0x02
+#define SR_IER_ERLSI 0x04
+#define SR_IER_EMS 0x08
+#define SR_IER_ALL 0x0F
+#define SER_DLM(x) ((x)+1)
+#define SER_IIR(x) ((x)+2)
+#define SER_FCR(x) ((x)+2)
+#define SR_FCR_ENABLE_FIFO 0x01
+#define SR_FCR_CLEAR_RCVR 0x02
+#define SR_FCR_CLEAR_XMIT 0x04
+#define SER_LCR(x) ((x)+3)
+#define SR_LCR_CS5 0x00
+#define SR_LCR_CS6 0x01
+#define SR_LCR_CS7 0x02
+#define SR_LCR_CS8 0x03
+#define SR_LCR_ST1 0x00
+#define SR_LCR_ST2 0x04
+#define SR_LCR_PNO 0x00
+#define SR_LCR_POD 0x08
+#define SR_LCR_PEV 0x18
+#define SR_LCR_PMK 0x28
+#define SR_LCR_PSP 0x38
+#define SR_LCR_BRK 0x40
+#define SR_LCR_DLAB 0x80
+#define SER_MCR(x) ((x)+4)
+#define SR_MCR_DTR 0x01
+#define SR_MCR_RTS 0x02
+#define SR_MCR_OUT1 0x04
+#define SR_MCR_OUT2 0x08
+#define SR_MCR_LOOP 0x10
+#define SER_LSR(x) ((x)+5)
+#define SR_LSR_DR 0x01
+#define SR_LSR_TBE 0x20
+#define SER_MSR(x) ((x)+6)
+#define SR_MSR_CTS 0x10
+#define SR_MSR_DSR 0x20
+#define SER_SCR(x) ((x)+7)
+
+
+/* GLOBAL VARIABLES *********************************************************/
+
+#define KdComPortInUse _KdComPortInUse
+ULONG KdComPortInUse = 0;
+
+/* STATIC VARIABLES *********************************************************/
+
+static ULONG ComPort = 0;
+static ULONG BaudRate = 0;
+static PUCHAR PortBase = (PUCHAR)0;
+
+/* The com port must only be initialized once! */
+static BOOLEAN PortInitialized = FALSE;
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+static BOOLEAN
+KdpDoesComPortExist (PUCHAR BaseAddress)
+{
+ BOOLEAN found;
+ UCHAR mcr;
+ UCHAR msr;
+
+ found = FALSE;
+
+ /* save Modem Control Register (MCR) */
+ mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
+
+ /* enable loop mode (set Bit 4 of the MCR) */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* clear all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0x00)
+ {
+ /* set all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0xF0)
+ {
+ /*
+ * setup a resonable state for the port:
+ * enable fifo and clear recieve/transmit buffers
+ */
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
+ (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
+ READ_PORT_UCHAR (SER_RBR(BaseAddress));
+ WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
+ found = TRUE;
+ }
+ }
+
+ /* restore MCR */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
+
+ return (found);
+}
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* HAL.KdPortInitialize */
+BOOLEAN
+STDCALL
+KdPortInitialize (
+ PKD_PORT_INFORMATION PortInformation,
+ ULONG Unknown1,
+ ULONG Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ char buffer[80];
+ ULONG divisor;
+ UCHAR lcr;
+
+ if (PortInitialized == FALSE)
+ {
+ if (PortInformation->BaudRate != 0)
+ {
+ BaudRate = PortInformation->BaudRate;
+ }
+ else
+ {
+ BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
+ {
+ PortBase = (PUCHAR)BaseArray[2];
+ ComPort = 2;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
+ {
+ PortBase = (PUCHAR)BaseArray[1];
+ ComPort = 1;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No COM port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ ComPort = PortInformation->ComPort;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No serial port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ PortInitialized = TRUE;
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(PortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ /*
+ * set global info
+ */
+ KdComPortInUse = (ULONG)PortBase;
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ ComPort,
+ (ULONG)PortBase,
+ BaudRate);
+
+ HalDisplayString (buffer);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortInitializeEx */
+BOOLEAN
+STDCALL
+KdPortInitializeEx (
+ PKD_PORT_INFORMATION PortInformation,
+ ULONG Unknown1,
+ ULONG Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ PUCHAR ComPortBase;
+ char buffer[80];
+ ULONG divisor;
+ UCHAR lcr;
+
+ if (PortInformation->BaudRate == 0)
+ {
+ PortInformation->BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ PortInformation->BaseAddress = (ULONG)ComPortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase];
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: Serial port not found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / PortInformation->BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+#ifndef NDEBUG
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase,
+ PortInformation->BaudRate);
+
+ HalDisplayString (buffer);
+
+#endif /* NDEBUG */
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortGetByte */
+BOOLEAN
+STDCALL
+KdPortGetByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortGetByteEx */
+BOOLEAN
+STDCALL
+KdPortGetByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortPollByte */
+BOOLEAN
+STDCALL
+KdPortPollByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortPollByteEx */
+BOOLEAN
+STDCALL
+KdPortPollByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+ return TRUE;
+}
+
+
+
+
+/* HAL.KdPortPutByte */
+VOID
+STDCALL
+KdPortPutByte (
+ UCHAR ByteToSend
+ )
+{
+ if (PortInitialized == FALSE)
+ return;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
+}
+
+/* HAL.KdPortPutByteEx */
+VOID
+STDCALL
+KdPortPutByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ UCHAR ByteToSend
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
+}
+
+
+/* HAL.KdPortRestore */
+VOID
+STDCALL
+KdPortRestore (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortSave */
+VOID
+STDCALL
+KdPortSave (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortDisableInterrupts */
+BOOLEAN
+STDCALL
+KdPortDisableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortEnableInterrupts */
+BOOLEAN
+STDCALL
+KdPortEnableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ ch |= SR_IER_ERDA;
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~SR_MCR_LOOP);
+ ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ return TRUE;
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/mca.c b/reactos/hal/halppc/generic/mca.c
new file mode 100644
index 00000000000..8343c8a8f70
--- /dev/null
+++ b/reactos/hal/halppc/generic/mca.c
@@ -0,0 +1,79 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: mca.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mca.c
+ * PURPOSE: Interfaces to the MicroChannel bus
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/*
+ * TODO:
+ * What Adapter ID is read from an empty slot?
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer;
+
+ DPRINT("HalpGetMicroChannelData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((BusNumber != 0) ||
+ (SlotNumber == 0) || (SlotNumber > 8) ||
+ (Length < sizeof(CM_MCA_POS_DATA)))
+ return(0);
+
+ /* Enter Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08));
+
+ /* Read POS data */
+ PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) +
+ READ_PORT_UCHAR((PUCHAR)0x100);
+ PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102);
+ PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103);
+ PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104);
+ PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105);
+
+ /* Leave Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07));
+
+ return(sizeof(CM_MCA_POS_DATA));
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/misc.c b/reactos/hal/halppc/generic/misc.c
new file mode 100644
index 00000000000..7eb1d9170f9
--- /dev/null
+++ b/reactos/hal/halppc/generic/misc.c
@@ -0,0 +1,105 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/misc.c
+ * PURPOSE: Miscellanous Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 ("\n*** Hardware Malfunction\n\n");
+ HalDisplayString ("Call your hardware vendor for support\n\n");
+
+ /* Check for parity error */
+ if (ucStatus & 0x80)
+ {
+ /* Display message */
+ HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
+ }
+
+ /* Check for I/O failure */
+ if (ucStatus & 0x40)
+ {
+ /* Display message */
+ HalDisplayString ("NMI: Channel Check / IOCHK\n");
+ }
+
+ /* Halt the system */
+ HalDisplayString("\n*** The system has halted ***\n");
+ //KeEnterKernelDebugger();
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+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;
+}
diff --git a/reactos/hal/halppc/generic/pci.c b/reactos/hal/halppc/generic/pci.c
new file mode 100644
index 00000000000..51d5910f50f
--- /dev/null
+++ b/reactos/hal/halppc/generic/pci.c
@@ -0,0 +1,778 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/pci.c
+ * PURPOSE: PCI Bus Support (Configuration Space, Resource Allocation)
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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('H', 'a', 'l', ' '));
+ 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 */
diff --git a/reactos/hal/halppc/generic/portio.c b/reactos/hal/halppc/generic/portio.c
new file mode 100644
index 00000000000..19caddccc11
--- /dev/null
+++ b/reactos/hal/halppc/generic/portio.c
@@ -0,0 +1,283 @@
+/* $Id: portio.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/portio.c
+ * PURPOSE: Port I/O functions
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 18/10/99
+ */
+
+#include
+#define NDEBUG
+#include
+
+/* 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 STDCALL
+READ_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+ while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); }
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+ while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); }
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+ while(Count--) { *Buffer++ = GetPhys((ULONG)Port); }
+}
+
+UCHAR STDCALL
+READ_PORT_UCHAR (PUCHAR Port)
+{
+ return GetPhys((ULONG)Port);
+}
+
+USHORT STDCALL
+READ_PORT_USHORT (PUSHORT Port)
+{
+ return GetPhysWord((ULONG)Port);
+}
+
+ULONG STDCALL
+READ_PORT_ULONG (PULONG Port)
+{
+ return GetPhys((ULONG)Port);
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+ while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); }
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+ while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); }
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+ while(Count--) { SetPhys((ULONG)Port, *Buffer++); }
+}
+
+VOID STDCALL
+WRITE_PORT_UCHAR (PUCHAR Port,
+ UCHAR Value)
+{
+ SetPhysByte((ULONG)Port, Value);
+}
+
+VOID STDCALL
+WRITE_PORT_USHORT (PUSHORT Port,
+ USHORT Value)
+{
+ SetPhysWord((ULONG)Port, Value);
+}
+
+VOID STDCALL
+WRITE_PORT_ULONG (PULONG Port,
+ ULONG Value)
+{
+ SetPhys((ULONG)Port, Value);
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/processor.c b/reactos/hal/halppc/generic/processor.c
new file mode 100644
index 00000000000..430435319ac
--- /dev/null
+++ b/reactos/hal/halppc/generic/processor.c
@@ -0,0 +1,76 @@
+/* $Id: processor.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/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
+#define NDEBUG
+#include
+
+/* FUNCTIONS *****************************************************************/
+
+#define INITIAL_STALL_COUNT 0x10000
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+ PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock);
+ KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT;
+}
+
+BOOLEAN STDCALL
+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 */
diff --git a/reactos/hal/halppc/generic/profil.c b/reactos/hal/halppc/generic/profil.c
new file mode 100644
index 00000000000..b8dec298311
--- /dev/null
+++ b/reactos/hal/halppc/generic/profil.c
@@ -0,0 +1,61 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/profil.c
+ * PURPOSE: System Profiling
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
+{
+ KEBUGCHECK(0);
+ return;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
+{
+ KEBUGCHECK(0);
+ return;
+}
+
+/*
+ * @unimplemented
+ */
+ULONG_PTR
+NTAPI
+HalSetProfileInterval(IN ULONG_PTR Interval)
+{
+ KEBUGCHECK(0);
+ 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;
+}
diff --git a/reactos/hal/halppc/generic/pwroff.c b/reactos/hal/halppc/generic/pwroff.c
new file mode 100644
index 00000000000..cf6be7555b9
--- /dev/null
+++ b/reactos/hal/halppc/generic/pwroff.c
@@ -0,0 +1,121 @@
+/* $Id: pwroff.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * FILE : reactos/hal/x86/apm.c
+ * DESCRIPTION: Turn CPU off...
+ * PROJECT : ReactOS Operating System
+ * AUTHOR : D. Lindauer (July 11 1997)
+ * NOTE : This program is public domain
+ * REVISIONS :
+ * 1999-12-26
+ */
+
+#define APM_FUNCTION_AVAILABLE 0x5300
+#define APM_FUNCTION_CONNREAL 0x5301
+#define APM_FUNCTION_POWEROFF 0x5307
+#define APM_FUNCTION_ENABLECPU 0x530d
+#define APM_FUNCTION_ENABLEAPM 0x530e
+
+#define APM_DEVICE_BIOS 0
+#define APM_DEVICE_ALL 1
+
+#define APM_MODE_DISABLE 0
+#define APM_MODE_ENABLE 1
+
+
+
+#if defined(__GNUC__)
+
+nopm db 'No power management functionality',10,13,'$'
+errmsg db 'Power management error',10,13,'$'
+wrongver db 'Need APM version 1.1 or better',10,13,'$'
+;
+; Entry point
+;
+go:
+ mov dx,offset nopm
+ jc error
+ cmp ax,101h ; See if version 1.1 or greater
+ mov dx,offset wrongver
+ jc error
+
+ mov [ver],ax
+ mov ax,5301h ; Do a real mode connection
+ mov bx,0 ; device = BIOS
+ int 15h
+ jnc noconerr
+
+ cmp ah,2 ; Pass if already connected
+ mov dx,offset errmsg ; else error
+ jnz error
+noconerr:
+ mov ax,530eh ; Enable latest version of APM
+ mov bx,0 ; device = BIOS
+ mov cx,[ver] ; version
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530dh ; Now engage and enable CPU management
+ mov bx,1 ; device = all
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530fh
+ mov bx,1 ; device = ALL
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov dx,offset errmsg
+error:
+ call print
+ mov ax,4c01h
+ int 21h
+ int 3
+ end start
+
+
+BOOLEAN
+ApmCall (
+ DWORD Function,
+ DWORD Device,
+ DWORD Mode
+ )
+{
+ /* AX <== Function */
+ /* BX <== Device */
+ /* CX <== Mode */
+ __asm__("int 21\n"); /* 0x15 */
+}
+
+#elif defined(_MSC_VER)
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+BOOLEAN
+HalPowerOff (VOID)
+{
+ ApmCall (
+ APM_FUNCTION_AVAILABLE,
+ APM_DEVICE_BIOS,
+ 0
+ );
+ ApmCall (
+ APM_FUNCTION_ENABLEAPM,
+ );
+ /* Shutdown CPU */
+ ApmCall (
+ APM_FUNCTION_POWEROFF,
+ APM_DEVICE_ALL,
+ 3
+ );
+ return TRUE;
+}
+
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/reboot.c b/reactos/hal/halppc/generic/reboot.c
new file mode 100644
index 00000000000..89ab5c0d221
--- /dev/null
+++ b/reactos/hal/halppc/generic/reboot.c
@@ -0,0 +1,41 @@
+/* $Id: reboot.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/reboot.c
+ * PURPOSE: Reboot functions.
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 11/10/99
+ */
+
+#include
+#define NDEBUG
+#include
+
+typedef void (*void_fun)();
+static VOID
+HalReboot (VOID)
+{
+ void_fun reset_vector = (void_fun)0xfff00100;
+ reset_vector();
+}
+
+
+VOID STDCALL
+HalReturnToFirmware (
+ FIRMWARE_REENTRY Action
+ )
+{
+ if (Action == HalHaltRoutine)
+ {
+ DbgPrint ("HalReturnToFirmware called!\n");
+ DbgBreakPoint ();
+ }
+ else if (Action == HalRebootRoutine)
+ {
+ HalReboot ();
+ }
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/resource.c b/reactos/hal/halppc/generic/resource.c
new file mode 100644
index 00000000000..acf17ff151d
--- /dev/null
+++ b/reactos/hal/halppc/generic/resource.c
@@ -0,0 +1,31 @@
+/* $Id: resource.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/resource.c
+ * PURPOSE: Miscellaneous resource functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+ /*
+ * FIXME: Report all resources used by hal.
+ * Calls IoReportHalResourceUsage()
+ */
+
+ /* Initialize PCI bus. */
+ HalpInitPciBus ();
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/spinlock.c b/reactos/hal/halppc/generic/spinlock.c
new file mode 100644
index 00000000000..987762c96b5
--- /dev/null
+++ b/reactos/hal/halppc/generic/spinlock.c
@@ -0,0 +1,210 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/up/spinlock.c
+ * PURPOSE: Spinlock and Queued Spinlock Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+#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 */
diff --git a/reactos/hal/halppc/generic/sysbus.c b/reactos/hal/halppc/generic/sysbus.c
new file mode 100644
index 00000000000..4955b122cfd
--- /dev/null
+++ b/reactos/hal/halppc/generic/sysbus.c
@@ -0,0 +1,66 @@
+/* $Id: sysbus.c 23907 2006-09-04 05:52:23Z arty $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/sysbus.c
+ * PURPOSE: System bus handler functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 09/04/2000 Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetSystemInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ ULONG BaseAddress = 0;
+
+ if (*AddressSpace == 0)
+ {
+ /* memory space */
+
+ }
+ else if (*AddressSpace == 1)
+ {
+ /* io space */
+
+ }
+ else
+ {
+ /* other */
+ return FALSE;
+ }
+
+ TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
+
+ return TRUE;
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/sysinfo.c b/reactos/hal/halppc/generic/sysinfo.c
new file mode 100644
index 00000000000..b27b2bc32c7
--- /dev/null
+++ b/reactos/hal/halppc/generic/sysinfo.c
@@ -0,0 +1,41 @@
+/*
+ * PROJECT: ReactOS HA:
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/sysinfo.c
+ * PURPOSE: HAL Information Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+#define KdComPortInUse _KdComPortInUse
+ULONG KdComPortInUse = 0;
+
+/* 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 */
diff --git a/reactos/hal/halppc/generic/systimer.S b/reactos/hal/halppc/generic/systimer.S
new file mode 100644
index 00000000000..285686675a7
--- /dev/null
+++ b/reactos/hal/halppc/generic/systimer.S
@@ -0,0 +1,48 @@
+/*
+ * FILE: hal/halx86/generic/timer.S
+ * COPYRIGHT: See COPYING in the top level directory
+ * PURPOSE: System Timer Interrupt and Management
+ * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#include
+.intel_syntax noprefix
+
+/* FUNCTIONS *****************************************************************/
+
+.globl _HalpClockInterrupt@0
+.func HalpClockInterrupt@0
+_HalpClockInterrupt@0:
+
+ /* Enter trap */
+ INT_PROLOG Hci, DoPushFakeErrorCode
+
+ /* Push vector and make stack for IRQL */
+ push 0x30
+ sub esp, 4
+
+ /* Begin the interrupt */
+ push esp
+ push 0x30
+ push CLOCK2_LEVEL
+ call _HalBeginSystemInterrupt@12
+
+ /* Check if it's spurious */
+ or al, al
+ jz Spurious
+
+ /* Do a tick */
+ mov eax, 100000
+ jmp _KeUpdateSystemTime@0
+
+Spurious:
+
+ /* Exit the interrupt */
+ add esp, 8
+ mov esi, $
+ jmp _Kei386EoiHelper@0
+.endfunc
+
diff --git a/reactos/hal/halppc/generic/time.c b/reactos/hal/halppc/generic/time.c
new file mode 100644
index 00000000000..bb81cc01cec
--- /dev/null
+++ b/reactos/hal/halppc/generic/time.c
@@ -0,0 +1,102 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/time.c
+ * PURPOSE: Getting time information
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+
+/* MACROS and CONSTANTS ******************************************************/
+
+/* macro BCD_INT : convert bcd to int */
+#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+
+/* macro INT_BCD : convert int to bcd */
+#define INT_BCD(int) (((int / 10) << 4) + (int % 10))
+
+
+#define RTC_REGISTER_A 0x0A
+#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
+
+#define RTC_REGISTER_B 0x0B
+
+#define RTC_REGISTER_CENTURY 0x32
+
+/* GLOBALS ******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN STDCALL
+HalQueryRealTimeClock(PTIME_FIELDS Time)
+{
+ return TRUE;
+}
+
+
+VOID STDCALL
+HalSetRealTimeClock(PTIME_FIELDS Time)
+{
+}
+
+
+BOOLEAN STDCALL
+HalGetEnvironmentVariable(PCH Name,
+ USHORT ValueLength,
+ PCH Value)
+{
+ strncpy(Value, "TRUE", ValueLength);
+ return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalSetEnvironmentVariable(PCH Name,
+ PCH Value)
+{
+ return TRUE;
+}
+
+
+ULONG STDCALL
+HalpGetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ DPRINT("HalpGetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ return 0;
+}
+
+
+ULONG STDCALL
+HalpSetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ DPRINT("HalpSetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ return 0;
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/generic/timer.c b/reactos/hal/halppc/generic/timer.c
new file mode 100644
index 00000000000..a3e23fc83dd
--- /dev/null
+++ b/reactos/hal/halppc/generic/timer.c
@@ -0,0 +1,138 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: hal/halx86/generic/timer.c
+ * PURPOSE: HAL Timer Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* 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 */
diff --git a/reactos/hal/halppc/include/apic.h b/reactos/hal/halppc/include/apic.h
new file mode 100644
index 00000000000..7454c210f72
--- /dev/null
+++ b/reactos/hal/halppc/include/apic.h
@@ -0,0 +1,214 @@
+/*
+ *
+ */
+
+#ifndef __INTERNAL_HAL_APIC_H
+#define __INTERNAL_HAL_APIC_H
+
+#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;
+}
+
+
+#endif
+
+
+/* EOF */
+
diff --git a/reactos/hal/halppc/include/bus.h b/reactos/hal/halppc/include/bus.h
new file mode 100644
index 00000000000..2c82d3ed61d
--- /dev/null
+++ b/reactos/hal/halppc/include/bus.h
@@ -0,0 +1,296 @@
+#ifndef __INTERNAL_HAL_BUS_H
+#define __INTERNAL_HAL_BUS_H
+
+//
+// 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;
+
+#endif /* __INTERNAL_HAL_BUS_H */
+
+/* EOF */
+
+
diff --git a/reactos/hal/halppc/include/hal.h b/reactos/hal/halppc/include/hal.h
new file mode 100644
index 00000000000..5220140dfe4
--- /dev/null
+++ b/reactos/hal/halppc/include/hal.h
@@ -0,0 +1,53 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Hardware Abstraction Layer
+ * FILE: hal/halx86/include/hal.h
+ * PURPOSE: HAL Header
+ * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES ******************************************************************/
+
+/* C Headers */
+#include
+
+/* WDK HAL Compilation hack */
+#ifdef _MSC_VER
+#include
+#include
+#undef _NTHAL_
+#undef DECLSPEC_IMPORT
+#define DECLSPEC_IMPORT
+#define __declspec(dllimport)
+#endif
+
+/* IFS/DDK/NDK Headers */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* 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"
+
+/* Helper Header */
+#include
+
+/* EOF */
diff --git a/reactos/hal/halppc/include/haldma.h b/reactos/hal/halppc/include/haldma.h
new file mode 100644
index 00000000000..59ddb9338a0
--- /dev/null
+++ b/reactos/hal/halppc/include/haldma.h
@@ -0,0 +1,383 @@
+#ifndef HALDMA_H
+#define HALDMA_H
+
+/*
+ * 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;
+
+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 STDCALL
+HalpDmaAllocateMasterAdapter(VOID);
+
+PDMA_ADAPTER STDCALL
+HalpGetDmaAdapter(
+ IN PVOID Context,
+ IN PDEVICE_DESCRIPTION DeviceDescription,
+ OUT PULONG NumberOfMapRegisters);
+
+ULONG STDCALL
+HalpDmaGetDmaAlignment(
+ PADAPTER_OBJECT AdapterObject);
+
+#endif /* HALDMA_H */
diff --git a/reactos/hal/halppc/include/halirq.h b/reactos/hal/halppc/include/halirq.h
new file mode 100644
index 00000000000..32b77abc8a3
--- /dev/null
+++ b/reactos/hal/halppc/include/halirq.h
@@ -0,0 +1,35 @@
+/*
+ * $Id: halirq.h 23669 2006-08-23 16:58:43Z ion $
+ */
+
+#ifndef __INCLUDE_HAL_HALIRQ
+#define __INCLUDE_HAL_HALIRQ
+
+#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
+
+#endif /* __INCLUDE_HAL_HALIRQ */
diff --git a/reactos/hal/halppc/include/halp.h b/reactos/hal/halppc/include/halp.h
new file mode 100644
index 00000000000..cb540295512
--- /dev/null
+++ b/reactos/hal/halppc/include/halp.h
@@ -0,0 +1,132 @@
+/*
+ *
+ */
+
+#ifndef __INTERNAL_HAL_HAL_H
+#define __INTERNAL_HAL_HAL_H
+
+/* Temporary hack */
+#define KPCR_BASE 0xFF000000
+
+/* WDK Hack */
+#define KdComPortInUse _KdComPortInUse
+
+#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 STDCALL 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;
+
+#endif /* __INTERNAL_HAL_HAL_H */
diff --git a/reactos/hal/halppc/include/ioapic.h b/reactos/hal/halppc/include/ioapic.h
new file mode 100644
index 00000000000..114853c4a6d
--- /dev/null
+++ b/reactos/hal/halppc/include/ioapic.h
@@ -0,0 +1,103 @@
+/*
+ *
+ */
+
+#ifndef __INTERNAL_HAL_IOAPIC_H
+#define __INTERNAL_HAL_IOAPIC_H
+
+/* 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
+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
+
+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);
+
+#endif
+
+
+
+/* EOF */
+
diff --git a/reactos/hal/halppc/include/mps.h b/reactos/hal/halppc/include/mps.h
new file mode 100644
index 00000000000..83f9cfbe501
--- /dev/null
+++ b/reactos/hal/halppc/include/mps.h
@@ -0,0 +1,204 @@
+#ifndef __INCLUDE_HAL_MPS
+#define __INCLUDE_HAL_MPS
+
+/*
+ * 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
+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
+
+#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);
+
+
+#endif /* __INCLUDE_HAL_MPS */
+
+/* EOF */
diff --git a/reactos/hal/halppc/up/halinit_up.c b/reactos/hal/halppc/up/halinit_up.c
new file mode 100644
index 00000000000..cbb18bc665e
--- /dev/null
+++ b/reactos/hal/halppc/up/halinit_up.c
@@ -0,0 +1,32 @@
+/* $Id: halinit_up.c 24964 2006-11-29 08:28:20Z ion $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+
+}
+
+VOID
+HalpInitPhase1(VOID)
+{
+
+}
+
+/* EOF */
diff --git a/reactos/hal/halppc/up/halup.rbuild b/reactos/hal/halppc/up/halup.rbuild
new file mode 100644
index 00000000000..34efd0e7bbb
--- /dev/null
+++ b/reactos/hal/halppc/up/halup.rbuild
@@ -0,0 +1,13 @@
+
+
+
+ ../include
+ include
+
+
+
+ halppc_generic
+ ntoskrnl
+ halinit_up.c
+ halup.rc
+
diff --git a/reactos/hal/halppc/up/halup.rc b/reactos/hal/halppc/up/halup.rc
new file mode 100644
index 00000000000..90af6b929ff
--- /dev/null
+++ b/reactos/hal/halppc/up/halup.rc
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halup\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll\0"
+#include
diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h
index 7d10216dcee..43866dcd38e 100644
--- a/reactos/include/ddk/winddk.h
+++ b/reactos/include/ddk/winddk.h
@@ -5330,6 +5330,75 @@ typedef struct _KFLOATING_SAVE {
ULONG Dummy;
} KFLOATING_SAVE, *PKFLOATING_SAVE;
+#elif defined(__PowerPC__)
+
+typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
+
+#define PASSIVE_LEVEL 0
+#define LOW_LEVEL 0
+#define APC_LEVEL 1
+#define DISPATCH_LEVEL 2
+#define PROFILE_LEVEL 27
+#define CLOCK1_LEVEL 28
+#define CLOCK2_LEVEL 28
+#define IPI_LEVEL 29
+#define POWER_LEVEL 30
+#define HIGH_LEVEL 31
+
+typedef struct _KFLOATING_SAVE {
+ ULONG Dummy;
+} KFLOATING_SAVE, *PKFLOATING_SAVE;
+
+typedef struct _KPCR_TIB {
+ PVOID ExceptionList; /* 00 */
+ PVOID StackBase; /* 04 */
+ PVOID StackLimit; /* 08 */
+ PVOID SubSystemTib; /* 0C */
+ _ANONYMOUS_UNION union {
+ PVOID FiberData; /* 10 */
+ DWORD Version; /* 10 */
+ } DUMMYUNIONNAME;
+ PVOID ArbitraryUserPointer; /* 14 */
+ struct _KPCR_TIB *Self; /* 18 */
+} KPCR_TIB, *PKPCR_TIB; /* 1C */
+
+#define PCR_MINOR_VERSION 1
+#define PCR_MAJOR_VERSION 1
+
+typedef struct _KPCR {
+ KPCR_TIB Tib; /* 00 */
+ struct _KPCR *Self; /* 1C */
+ struct _KPRCB *Prcb; /* 20 */
+ KIRQL Irql; /* 24 */
+ ULONG IRR; /* 28 */
+ ULONG IrrActive; /* 2C */
+ ULONG IDR; /* 30 */
+ PVOID KdVersionBlock; /* 34 */
+ PUSHORT IDT; /* 38 */
+ PUSHORT GDT; /* 3C */
+ struct _KTSS *TSS; /* 40 */
+ USHORT MajorVersion; /* 44 */
+ USHORT MinorVersion; /* 46 */
+ KAFFINITY SetMember; /* 48 */
+ ULONG StallScaleFactor; /* 4C */
+ UCHAR SpareUnused; /* 50 */
+ UCHAR Number; /* 51 */
+} KPCR, *PKPCR; /* 54 */
+
+static __inline
+ULONG
+DDKAPI
+KeGetCurrentProcessorNumber(VOID)
+{
+ ULONG Number;
+ __asm__ __volatile__ (
+ "lwz %0, %c1(12)\n"
+ : "=r" (Number)
+ : "i" (FIELD_OFFSET(KPCR, Number))
+ );
+ return Number;
+}
+
#else
#error Unknown architecture
#endif
diff --git a/reactos/include/ndk/powerpc/ketypes.h b/reactos/include/ndk/powerpc/ketypes.h
index 739fb7ae854..4d870b34b8d 100644
--- a/reactos/include/ndk/powerpc/ketypes.h
+++ b/reactos/include/ndk/powerpc/ketypes.h
@@ -31,81 +31,155 @@ Author:
#define IPI_FREEZE 3
#define IPI_PACKET_READY 4
#define IPI_SYNCH_REQUEST 10
+#define MAXIMUM_VECTOR 0x100
+
+#define KSEG0_BASE 0x80000000
+
+#define PRCB_MAJOR_VERSION 1
+#define PRCB_BUILD_DEBUG 1
+
+#ifndef ROUND_UP
+#define ROUND_UP(x,y) (((x) + ((y)-1)) & ~((y)-1))
+#endif
+
+typedef double DOUBLE;
+
+typedef struct _FX_SAVE_AREA {
+ ULONG Fr[32];
+} FX_SAVE_AREA;
+
+typedef struct _LDT_ENTRY {
+ USHORT LimitLow;
+ USHORT BaseLow;
+ union
+ {
+ struct
+ {
+ UCHAR BaseMid;
+ UCHAR Flags1;
+ UCHAR Flags2;
+ UCHAR BaseHi;
+ } Bytes;
+ struct
+ {
+ ULONG BaseMid : 8;
+ ULONG Type : 5;
+ ULONG Dpl : 2;
+ ULONG Pres : 1;
+ ULONG LimitHi : 4;
+ ULONG Sys : 1;
+ ULONG Reserved_0 : 1;
+ ULONG Default_Big : 1;
+ ULONG Granularity : 1;
+ ULONG BaseHi : 8;
+ } Bits;
+ } HighWord;
+} LDT_ENTRY;
+
+#ifndef CONFIG_SMP
+#define SYNCH_LEVEL DISPATCH_LEVEL
+#else
+#define SYNCH_LEVEL (IPI_LEVEL - 1)
+#endif
//
// Trap Frame Definition
//
typedef struct _KTRAP_FRAME
{
- PVOID TrapFrame;
- UCHAR OldIrql;
- UCHAR PreviousMode;
- UCHAR SavedApcStateIndex;
- UCHAR SavedKernelApcDisable;
- UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), ULONGLONG];
- ULONG FILL2;
- ULONG Gpr0;
- ULONG Gpr1;
- ULONG Gpr2;
- ULONG Gpr3;
- ULONG Gpr4;
- ULONG Gpr5;
- ULONG Gpr6;
- ULONG Gpr7;
- ULONG Gpr8;
- ULONG Gpr9;
- ULONG Gpr10;
- ULONG Gpr11;
- ULONG Gpr12;
- DOUBLE Fpr0;
- DOUBLE Fpr1;
- DOUBLE Fpr2;
- DOUBLE Fpr3;
- DOUBLE Fpr4;
- DOUBLE Fpr5;
- DOUBLE Fpr6;
- DOUBLE Fpr7;
- DOUBLE Fpr8;
- DOUBLE Fpr9;
- DOUBLE Fpr10;
- DOUBLE Fpr11;
- DOUBLE Fpr12;
- DOUBLE Fpr13;
- DOUBLE Fpscr;
- ULONG Cr;
- ULONG Xer;
- ULONG Msr;
- ULONG Iar;
- ULONG Lr;
- ULONG Ctr;
- ULONG Dr0;
- ULONG Dr1;
- ULONG Dr2;
- ULONG Dr3;
- ULONG Dr4;
- ULONG Dr5;
- ULONG Dr6;
+ PVOID TrapFrame;
+ UCHAR OldIrql;
+ UCHAR PreviousMode;
+ UCHAR SavedApcStateIndex;
+ UCHAR SavedKernelApcDisable;
+ UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), sizeof(ULONGLONG))];
+ ULONG FILL2;
+ ULONG Gpr0;
+ ULONG Gpr1;
+ ULONG Gpr2;
+ ULONG Gpr3;
+ ULONG Gpr4;
+ ULONG Gpr5;
+ ULONG Gpr6;
+ ULONG Gpr7;
+ ULONG Gpr8;
+ ULONG Gpr9;
+ ULONG Gpr10;
+ ULONG Gpr11;
+ ULONG Gpr12;
+ DOUBLE Fpr0;
+ DOUBLE Fpr1;
+ DOUBLE Fpr2;
+ DOUBLE Fpr3;
+ DOUBLE Fpr4;
+ DOUBLE Fpr5;
+ DOUBLE Fpr6;
+ DOUBLE Fpr7;
+ DOUBLE Fpr8;
+ DOUBLE Fpr9;
+ DOUBLE Fpr10;
+ DOUBLE Fpr11;
+ DOUBLE Fpr12;
+ DOUBLE Fpr13;
+ DOUBLE Fpscr;
+ ULONG Cr;
+ ULONG Xer;
+ ULONG Msr;
+ ULONG Iar;
+ ULONG Lr;
+ ULONG Ctr;
+ ULONG Dr0;
+ ULONG Dr1;
+ ULONG Dr2;
+ ULONG Dr3;
+ ULONG Dr4;
+ ULONG Dr5;
+ ULONG Dr6;
ULONG Dr7;
} KTRAP_FRAME, *PKTRAP_FRAME;
//
-// Page Table Entry Definition
+// GDT Entry Definition
//
-typedef struct _HARDWARE_PTE_PPC
+typedef struct _KGDTENTRY
{
- ULONG Dirty:2;
- ULONG Valid:1;
- ULONG GuardedStorage:1;
- ULONG MemoryCoherence:1;
- ULONG CacheDisable:1;
- ULONG WriteThrough:1;
- ULONG Change:1;
- ULONG Reference:1;
- ULONG Write:1;
- ULONG CopyOnWrite:1;
- ULONG rsvd1:1;
- ULONG PageFrameNumber:20;
-} HARDWARE_PTE_PPC, *PHARDWARE_PTE_PPC;
+ USHORT LimitLow;
+ USHORT BaseLow;
+ union
+ {
+ struct
+ {
+ UCHAR BaseMid;
+ UCHAR Flags1;
+ UCHAR Flags2;
+ UCHAR BaseHi;
+ } Bytes;
+ struct
+ {
+ ULONG BaseMid:8;
+ ULONG Type:5;
+ ULONG Dpl:2;
+ ULONG Pres:1;
+ ULONG LimitHi:4;
+ ULONG Sys:1;
+ ULONG Reserved_0:1;
+ ULONG Default_Big:1;
+ ULONG Granularity:1;
+ ULONG BaseHi:8;
+ } Bits;
+ } HighWord;
+} KGDTENTRY, *PKGDTENTRY;
+
+//
+// IDT Entry Definition
+//
+typedef struct _KIDTENTRY
+{
+ USHORT Offset;
+ USHORT Selector;
+ USHORT Access;
+ USHORT ExtendedOffset;
+} KIDTENTRY, *PKIDTENTRY;
typedef struct _DESCRIPTOR
{
@@ -119,49 +193,49 @@ typedef struct _DESCRIPTOR
//
typedef struct _KSPECIAL_REGISTERS
{
- ULONG KernelDr0;
- ULONG KernelDr1;
- ULONG KernelDr2;
- ULONG KernelDr3;
- ULONG KernelDr4;
- ULONG KernelDr5;
- ULONG KernelDr6;
- ULONG KernelDr7;
- ULONG Sprg0;
- ULONG Sprg1;
- ULONG Sr0;
- ULONG Sr1;
- ULONG Sr2;
- ULONG Sr3;
- ULONG Sr4;
- ULONG Sr5;
- ULONG Sr6;
- ULONG Sr7;
- ULONG Sr8;
- ULONG Sr9;
- ULONG Sr10;
- ULONG Sr11;
- ULONG Sr12;
- ULONG Sr13;
- ULONG Sr14;
- ULONG Sr15;
- ULONG DBAT0L;
- ULONG DBAT0U;
- ULONG DBAT1L;
- ULONG DBAT1U;
- ULONG DBAT2L;
- ULONG DBAT2U;
- ULONG DBAT3L;
- ULONG DBAT3U;
- ULONG IBAT0L;
- ULONG IBAT0U;
- ULONG IBAT1L;
- ULONG IBAT1U;
- ULONG IBAT2L;
- ULONG IBAT2U;
- ULONG IBAT3L;
- ULONG IBAT3U;
- ULONG Sdr1;
+ ULONG KernelDr0;
+ ULONG KernelDr1;
+ ULONG KernelDr2;
+ ULONG KernelDr3;
+ ULONG KernelDr4;
+ ULONG KernelDr5;
+ ULONG KernelDr6;
+ ULONG KernelDr7;
+ ULONG Sprg0;
+ ULONG Sprg1;
+ ULONG Sr0;
+ ULONG Sr1;
+ ULONG Sr2;
+ ULONG Sr3;
+ ULONG Sr4;
+ ULONG Sr5;
+ ULONG Sr6;
+ ULONG Sr7;
+ ULONG Sr8;
+ ULONG Sr9;
+ ULONG Sr10;
+ ULONG Sr11;
+ ULONG Sr12;
+ ULONG Sr13;
+ ULONG Sr14;
+ ULONG Sr15;
+ ULONG DBAT0L;
+ ULONG DBAT0U;
+ ULONG DBAT1L;
+ ULONG DBAT1U;
+ ULONG DBAT2L;
+ ULONG DBAT2U;
+ ULONG DBAT3L;
+ ULONG DBAT3U;
+ ULONG IBAT0L;
+ ULONG IBAT0U;
+ ULONG IBAT1L;
+ ULONG IBAT1U;
+ ULONG IBAT2L;
+ ULONG IBAT2U;
+ ULONG IBAT3L;
+ ULONG IBAT3U;
+ ULONG Sdr1;
ULONG Reserved[9];
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
@@ -171,9 +245,9 @@ typedef struct _KSPECIAL_REGISTERS
#pragma pack(push,4)
typedef struct _KPROCESSOR_STATE
{
- PCONTEXT ContextFrame;
+ CONTEXT ContextFrame;
KSPECIAL_REGISTERS SpecialRegisters;
-} KPROCESSOR_STATE;
+} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
//
// Processor Region Control Block
@@ -195,8 +269,13 @@ typedef struct _KPRCB
KPROCESSOR_STATE ProcessorState;
ULONG KernelReserved[16];
ULONG HalReserved[16];
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ ULONG CFlushSize;
+ UCHAR PrcbPad0[88];
+#else
UCHAR PrcbPad0[92];
- PVOID LockQueue[33]; // Used for Queued Spinlocks
+#endif
+ KSPIN_LOCK_QUEUE LockQueue[LockQueueMaximumLock];
struct _KTHREAD *NpxThread;
ULONG InterruptCount;
ULONG KernelTime;
@@ -208,19 +287,41 @@ typedef struct _KPRCB
ULONG PageColor;
UCHAR SkipTick;
UCHAR DebuggerSavedIRQL;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+ UCHAR NodeColor;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ UCHAR PollSlot;
+#else
+ UCHAR Spare1;
+#endif
+ ULONG NodeShiftedColor;
+#else
UCHAR Spare1[6];
+#endif
struct _KNODE *ParentNode;
ULONG MultiThreadProcessorSet;
struct _KPRCB *MultiThreadSetMaster;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+ ULONG SecondaryColorMask;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ ULONG DpcTimeLimit;
+#else
+ LONG Sleeping;
+#endif
+#else
ULONG ThreadStartCount[2];
+#endif
ULONG CcFastReadNoWait;
ULONG CcFastReadWait;
ULONG CcFastReadNotPossible;
ULONG CcCopyReadNoWait;
ULONG CcCopyReadWait;
ULONG CcCopyReadNoWaitMiss;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
ULONG KeAlignmentFixupCount;
- ULONG KeContextSwitches;
+#endif
+ ULONG SpareCounter0;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
ULONG KeDcacheFlushCount;
ULONG KeExceptionDispatchCount;
ULONG KeFirstLevelTbFills;
@@ -228,84 +329,170 @@ typedef struct _KPRCB
ULONG KeIcacheFlushCount;
ULONG KeSecondLevelTbFills;
ULONG KeSystemCalls;
- ULONG IoReadOperationCount;
- ULONG IoWriteOperationCount;
- ULONG IoOtherOperationCount;
+#endif
+ volatile ULONG IoReadOperationCount;
+ volatile ULONG IoWriteOperationCount;
+ volatile ULONG IoOtherOperationCount;
LARGE_INTEGER IoReadTransferCount;
LARGE_INTEGER IoWriteTransferCount;
LARGE_INTEGER IoOtherTransferCount;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ ULONG CcFastMdlReadNoWait;
+ ULONG CcFastMdlReadWait;
+ ULONG CcFastMdlReadNotPossible;
+ ULONG CcMapDataNoWait;
+ ULONG CcMapDataWait;
+ ULONG CcPinMappedDataCount;
+ ULONG CcPinReadNoWait;
+ ULONG CcPinReadWait;
+ ULONG CcMdlReadNoWait;
+ ULONG CcMdlReadWait;
+ ULONG CcLazyWriteHotSpots;
+ ULONG CcLazyWriteIos;
+ ULONG CcLazyWritePages;
+ ULONG CcDataFlushes;
+ ULONG CcDataPages;
+ ULONG CcLostDelayedWrites;
+ ULONG CcFastReadResourceMiss;
+ ULONG CcCopyReadWaitMiss;
+ ULONG CcFastMdlReadResourceMiss;
+ ULONG CcMapDataNoWaitMiss;
+ ULONG CcMapDataWaitMiss;
+ ULONG CcPinReadNoWaitMiss;
+ ULONG CcPinReadWaitMiss;
+ ULONG CcMdlReadNoWaitMiss;
+ ULONG CcMdlReadWaitMiss;
+ ULONG CcReadAheadIos;
+ ULONG KeAlignmentFixupCount;
+ ULONG KeExceptionDispatchCount;
+ ULONG KeSystemCalls;
+ ULONG PrcbPad1[3];
+#else
ULONG SpareCounter1[8];
+#endif
PP_LOOKASIDE_LIST PPLookasideList[16];
PP_LOOKASIDE_LIST PPNPagedLookasideList[32];
PP_LOOKASIDE_LIST PPPagedLookasideList[32];
- ULONG PacketBarrier;
- ULONG ReverseStall;
+ volatile ULONG PacketBarrier;
+ volatile ULONG ReverseStall;
PVOID IpiFrame;
UCHAR PrcbPad2[52];
- PVOID CurrentPacket[3];
- ULONG TargetSet;
- ULONG_PTR WorkerRoutine;
- ULONG IpiFrozen;
+ volatile PVOID CurrentPacket[3];
+ volatile ULONG TargetSet;
+ volatile PKIPI_WORKER WorkerRoutine;
+ volatile ULONG IpiFrozen;
UCHAR PrcbPad3[40];
- ULONG RequestSummary;
- struct _KPRCB *SignalDone;
+ volatile ULONG RequestSummary;
+ volatile struct _KPRCB *SignalDone;
UCHAR PrcbPad4[56];
struct _KDPC_DATA DpcData[2];
PVOID DpcStack;
ULONG MaximumDpcQueueDepth;
ULONG DpcRequestRate;
ULONG MinimumDpcRate;
- UCHAR DpcInterruptRequested;
- UCHAR DpcThreadRequested;
- UCHAR DpcRoutineActive;
- UCHAR DpcThreadActive;
+ volatile UCHAR DpcInterruptRequested;
+ volatile UCHAR DpcThreadRequested;
+ volatile UCHAR DpcRoutineActive;
+ volatile UCHAR DpcThreadActive;
ULONG PrcbLock;
ULONG DpcLastCount;
- ULONG TimerHand;
- ULONG TimerRequest;
+ volatile ULONG TimerHand;
+ volatile ULONG TimerRequest;
PVOID DpcThread;
- struct _KEVENT *DpcEvent;
+ KEVENT DpcEvent;
UCHAR ThreadDpcEnable;
- BOOLEAN QuantumEnd;
+ volatile BOOLEAN QuantumEnd;
UCHAR PrcbPad50;
- UCHAR IdleSchedule;
- ULONG DpcSetEventRequest;
+ volatile UCHAR IdleSchedule;
+ LONG DpcSetEventRequest;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ LONG Sleeping;
+ ULONG PeriodicCount;
+ ULONG PeriodicBias;
+ UCHAR PrcbPad5[6];
+#else
UCHAR PrcbPad5[18];
+#endif
LONG TickOffset;
- struct _KDPC* CallDpc;
+ KDPC CallDpc;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ LONG ClockKeepAlive;
+ UCHAR ClockCheckSlot;
+ UCHAR ClockPollCycle;
+ UCHAR PrcbPad6[2];
+ LONG DpcWatchdogPeriod;
+ LONG DpcWatchDogCount;
+ LONG ThreadWatchdogPeriod;
+ LONG ThreadWatchDogCount;
+ ULONG PrcbPad70[2];
+#else
ULONG PrcbPad7[8];
+#endif
LIST_ENTRY WaitListHead;
ULONG ReadySummary;
- ULONG SelectNextLast;
+ ULONG QueueIndex;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ SINGLE_LIST_ENTRY DeferredReadyListHead;
+ ULONGLONG StartCycles;
+ ULONGLONG CycleTime;
+ ULONGLONG PrcbPad71[3];
+ LIST_ENTRY DispatcherReadyListHead[32];
+#else
LIST_ENTRY DispatcherReadyListHead[32];
SINGLE_LIST_ENTRY DeferredReadyListHead;
ULONG PrcbPad72[11];
+#endif
PVOID ChainedInterruptList;
LONG LookasideIrpFloat;
- LONG MmPageFaultCount;
- LONG MmCopyOnWriteCount;
- LONG MmTransitionCount;
- LONG MmCacheTransitionCount;
- LONG MmDemandZeroCount;
- LONG MmPageReadCount;
- LONG MmPageReadIoCount;
- LONG MmCacheReadCount;
- LONG MmCacheIoCount;
- LONG MmDirtyPagesWriteCount;
- LONG MmDirtyWriteIoCount;
- LONG MmMappedPagesWriteCount;
- LONG MmMappedWriteIoCount;
+ volatile LONG MmPageFaultCount;
+ volatile LONG MmCopyOnWriteCount;
+ volatile LONG MmTransitionCount;
+ volatile LONG MmCacheTransitionCount;
+ volatile LONG MmDemandZeroCount;
+ volatile LONG MmPageReadCount;
+ volatile LONG MmPageReadIoCount;
+ volatile LONG MmCacheReadCount;
+ volatile LONG MmCacheIoCount;
+ volatile LONG MmDirtyPagesWriteCount;
+ volatile LONG MmDirtyWriteIoCount;
+ volatile LONG MmMappedPagesWriteCount;
+ volatile LONG MmMappedWriteIoCount;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ ULONG CachedCommit;
+ ULONG CachedResidentAvailable;
+ PVOID HyperPte;
+ UCHAR CpuVendor;
+ UCHAR PrcbPad9[3];
+#else
ULONG SpareFields0[1];
+#endif
CHAR VendorString[13];
UCHAR InitialApicId;
UCHAR LogicalProcessorsPerPhysicalProcessor;
ULONG MHz;
ULONG FeatureBits;
LARGE_INTEGER UpdateSignature;
- LARGE_INTEGER IsrTime;
+ volatile LARGE_INTEGER IsrTime;
LARGE_INTEGER SpareField1;
FX_SAVE_AREA NpxSaveArea;
PROCESSOR_POWER_STATE PowerState;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ KDPC DpcWatchdogDoc;
+ KTIMER DpcWatchdogTimer;
+ PVOID WheaInfo;
+ PVOID EtwSupport;
+ SLIST_HEADER InterruptObjectPool;
+ LARGE_INTEGER HyperCallPagePhysical;
+ LARGE_INTEGER HyperCallPageVirtual;
+ PVOID RateControl;
+ CACHE_DESCRIPTOR Cache[5];
+ ULONG CacheCount;
+ ULONG CacheProcessorMask[5];
+ UCHAR LogicalProcessorsPerCore;
+ UCHAR PrcbPad8[3];
+ ULONG PackageProcessorSet;
+ ULONG CoreProcessorSet;
+#endif
} KPRCB, *PKPRCB;
//
@@ -313,89 +500,89 @@ typedef struct _KPRCB
//
typedef struct _KIPCR
{
- USHORT MinorVersion;
- USHORT MajorVersion;
- PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
- ULONG PcrPage2;
- ULONG Kseg0Top;
+ USHORT MinorVersion;
+ USHORT MajorVersion;
+ PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
+ ULONG PcrPage2;
+ ULONG Kseg0Top;
ULONG Spare7[30];
- ULONG FirstLevelDcacheSize;
- ULONG FirstLevelDcacheFillSize;
- ULONG FirstLevelIcacheSize;
- ULONG FirstLevelIcacheFillSize;
- ULONG SecondLevelDcacheSize;
- ULONG SecondLevelDcacheFillSize;
- ULONG SecondLevelIcacheSize;
+ ULONG FirstLevelDcacheSize;
+ ULONG FirstLevelDcacheFillSize;
+ ULONG FirstLevelIcacheSize;
+ ULONG FirstLevelIcacheFillSize;
+ ULONG SecondLevelDcacheSize;
+ ULONG SecondLevelDcacheFillSize;
+ ULONG SecondLevelIcacheSize;
ULONG SecondLevelIcacheFillSize;
- struct _KPRCB *Prcb;
+ struct _KPRCB *PrcbData;
PVOID Teb;
- ULONG DcacheAlignment;
+ ULONG DcacheAlignment;
ULONG DcacheFillSize;
- ULONG IcacheAlignment;
+ ULONG IcacheAlignment;
ULONG IcacheFillSize;
- ULONG ProcessorVersion;
+ ULONG ProcessorVersion;
ULONG ProcessorRevision;
- ULONG ProfileInterval;
- ULONG ProfileCount;
- ULONG StallExecutionCount;
+ ULONG ProfileInterval;
+ ULONG ProfileCount;
+ ULONG StallExecutionCount;
ULONG StallScaleFactor;
ULONG Spare;
- union
- {
- ULONG CachePolicy;
- struct
- {
- UCHAR IcacheMode;
- UCHAR DcacheMode;
- USHORT ModeSpare;
- };
- };
- UCHAR IrqlMask[32];
+ union
+ {
+ ULONG CachePolicy;
+ struct
+ {
+ UCHAR IcacheMode;
+ UCHAR DcacheMode;
+ USHORT ModeSpare;
+ };
+ };
+ UCHAR IrqlMask[32];
UCHAR IrqlTable[9];
- UCHAR CurrentIrql;
- CCHAR Number;
- KAFFINITY SetMember;
- ULONG ReservedVectors;
- struct _KTHREAD *CurrentThread;
- ULONG AlignedCachePolicy;
- union
- {
- ULONG SoftwareInterrupt;
- struct
- {
- UCHAR ApcInterrupt;
- UCHAR DispatchInterrupt;
- UCHAR Spare4;
- UCHAR Spare5;
- };
- };
- KAFFINITY NotMember;
- ULONG SystemReserved[16];
- ULONG HalReserved[16];
- ULONG FirstLevelActive;
- ULONG SystemServiceDispatchStart;
- ULONG SystemServiceDispatchEnd;
- ULONG InterruptStack;
- ULONG QuantumEnd;
- PVOID InitialStack;
- PVOID PanicStack;
- ULONG BadVaddr;
- PVOID StackLimit;
- PVOID SavedStackLimit;
- ULONG SavedV0;
- ULONG SavedV1;
- UCHAR DebugActive;
- UCHAR Spare6[3];
- ULONG GprSave[6];
- ULONG SiR0;
- ULONG SiR2;
- ULONG SiR3;
- ULONG SiR4;
- ULONG SiR5;
- ULONG Spare0;
- ULONG Spare8;
- ULONG PgDirRa;
- ULONG OnInterruptStack;
+ UCHAR CurrentIrql;
+ CCHAR Number;
+ KAFFINITY SetMember;
+ ULONG ReservedVectors;
+ struct _KTHREAD *CurrentThread;
+ ULONG AlignedCachePolicy;
+ union
+ {
+ ULONG SoftwareInterrupt;
+ struct
+ {
+ UCHAR ApcInterrupt;
+ UCHAR DispatchInterrupt;
+ UCHAR Spare4;
+ UCHAR Spare5;
+ };
+ };
+ KAFFINITY NotMember;
+ ULONG SystemReserved[16];
+ ULONG HalReserved[16];
+ ULONG FirstLevelActive;
+ ULONG SystemServiceDispatchStart;
+ ULONG SystemServiceDispatchEnd;
+ ULONG InterruptStack;
+ ULONG QuantumEnd;
+ PVOID InitialStack;
+ PVOID PanicStack;
+ ULONG BadVaddr;
+ PVOID StackLimit;
+ PVOID SavedStackLimit;
+ ULONG SavedV0;
+ ULONG SavedV1;
+ UCHAR DebugActive;
+ UCHAR Spare6[3];
+ ULONG GprSave[6];
+ ULONG SiR0;
+ ULONG SiR2;
+ ULONG SiR3;
+ ULONG SiR4;
+ ULONG SiR5;
+ ULONG Spare0;
+ ULONG Spare8;
+ ULONG PgDirRa;
+ ULONG OnInterruptStack;
ULONG SavedInitialStack;
} KIPCR, *PKIPCR;
#pragma pack(pop)
@@ -403,51 +590,59 @@ typedef struct _KIPCR
//
// TSS Definition
//
-typedef struct _KTSS, KTSS, *PKTSS;
+typedef struct _KTSS {
+} KTSS, *PKTSS;
//
// PowerPC Exception Frame
//
typedef struct _KEXCEPTION_FRAME
{
- ULONG Fill1;
- ULONG Gpr13;
- ULONG Gpr14;
- ULONG Gpr15;
- ULONG Gpr16;
- ULONG Gpr17;
- ULONG Gpr18;
- ULONG Gpr19;
- ULONG Gpr20;
- ULONG Gpr21;
- ULONG Gpr22;
- ULONG Gpr23;
- ULONG Gpr24;
- ULONG Gpr25;
- ULONG Gpr26;
- ULONG Gpr27;
- ULONG Gpr28;
- ULONG Gpr29;
- ULONG Gpr30;
- ULONG Gpr31;
- DOUBLE Fpr14;
- DOUBLE Fpr15;
- DOUBLE Fpr16;
- DOUBLE Fpr17;
- DOUBLE Fpr18;
- DOUBLE Fpr19;
- DOUBLE Fpr20;
- DOUBLE Fpr21;
- DOUBLE Fpr22;
- DOUBLE Fpr23;
- DOUBLE Fpr24;
- DOUBLE Fpr25;
- DOUBLE Fpr26;
- DOUBLE Fpr27;
- DOUBLE Fpr28;
- DOUBLE Fpr29;
- DOUBLE Fpr30;
+ ULONG Fill1;
+ ULONG Gpr13;
+ ULONG Gpr14;
+ ULONG Gpr15;
+ ULONG Gpr16;
+ ULONG Gpr17;
+ ULONG Gpr18;
+ ULONG Gpr19;
+ ULONG Gpr20;
+ ULONG Gpr21;
+ ULONG Gpr22;
+ ULONG Gpr23;
+ ULONG Gpr24;
+ ULONG Gpr25;
+ ULONG Gpr26;
+ ULONG Gpr27;
+ ULONG Gpr28;
+ ULONG Gpr29;
+ ULONG Gpr30;
+ ULONG Gpr31;
+ DOUBLE Fpr14;
+ DOUBLE Fpr15;
+ DOUBLE Fpr16;
+ DOUBLE Fpr17;
+ DOUBLE Fpr18;
+ DOUBLE Fpr19;
+ DOUBLE Fpr20;
+ DOUBLE Fpr21;
+ DOUBLE Fpr22;
+ DOUBLE Fpr23;
+ DOUBLE Fpr24;
+ DOUBLE Fpr25;
+ DOUBLE Fpr26;
+ DOUBLE Fpr27;
+ DOUBLE Fpr28;
+ DOUBLE Fpr29;
+ DOUBLE Fpr30;
DOUBLE Fpr31;
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
+FORCEINLINE
+struct _KPRCB *
+KeGetCurrentPrcb(VOID)
+{
+ return (struct _KPRCB *)(ULONG_PTR)__readfsdword(FIELD_OFFSET(KIPCR, PrcbData));
+}
+
#endif
diff --git a/reactos/include/ndk/powerpc/mmtypes.h b/reactos/include/ndk/powerpc/mmtypes.h
index c3eb927be71..2dde39f5c27 100644
--- a/reactos/include/ndk/powerpc/mmtypes.h
+++ b/reactos/include/ndk/powerpc/mmtypes.h
@@ -29,4 +29,35 @@ Author:
#define PAGE_SIZE 0x1000
#define PAGE_SHIFT 12L
+typedef unsigned long long MMPTE_HARDWARE;
+typedef unsigned long long MMPTE_SOFTWARE;
+typedef unsigned long long MMPTE_PROTOTYPE;
+typedef unsigned long long MMPTE_SUBSECTION;
+typedef unsigned long long MMPTE_TRANSITION;
+typedef unsigned long long MMPTE_LIST;
+
+//
+// Page Table Entry Definition
+//
+typedef struct _HARDWARE_PTE_PPC
+{
+ ULONG Dirty:2;
+ ULONG Valid:1;
+ ULONG GuardedStorage:1;
+ ULONG MemoryCoherence:1;
+ ULONG CacheDisable:1;
+ ULONG WriteThrough:1;
+ ULONG Change:1;
+ ULONG Reference:1;
+ ULONG Write:1;
+ ULONG CopyOnWrite:1;
+ ULONG rsvd1:1;
+ ULONG PageFrameNumber:20;
+} HARDWARE_PTE_PPC, *PHARDWARE_PTE_PPC;
+
+#ifndef HARDWARE_PTE
+#define HARDWARE_PTE HARDWARE_PTE_PPC
+#define PHARDWARE_PTE PHARDWARE_PTE_PPC
+#endif
+
#endif/*_POWERPC_MMTYPES_H*/
diff --git a/reactos/include/psdk/intrin_ppc.h b/reactos/include/psdk/intrin_ppc.h
new file mode 100644
index 00000000000..6dd40182e6e
--- /dev/null
+++ b/reactos/include/psdk/intrin_ppc.h
@@ -0,0 +1,969 @@
+/*
+ Compatibility header for GCC -- GCC equivalents of intrinsic
+ Microsoft Visual C++ functions. Originally developed for the ReactOS
+ () and TinyKrnl ()
+ projects.
+
+ Copyright (c) 2006 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 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
+ 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.
+*/
+
+#ifndef KJK_INTRIN_PPC_H_
+#define KJK_INTRIN_PPC_H_
+
+#ifndef __GNUC__
+#error Unsupported compiler
+#endif
+
+/*** Stack frame juggling ***/
+#define _ReturnAddress() (__builtin_return_address(0))
+#define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
+/* TODO: __getcallerseflags but how??? */
+
+
+/*** Atomic operations ***/
+/* TODO: _ReadBarrier */
+/* TODO: _WriteBarrier */
+
+#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
+#define _ReadWriteBarrier() __sync_synchronize()
+#else
+/* TODO: _ReadWriteBarrier() */
+#endif
+
+#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
+
+static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
+{
+ return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
+{
+ return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
+{
+ return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+}
+
+static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
+{
+ return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+}
+
+static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
+{
+ return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
+{
+ /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
+ __sync_synchronize();
+ return __sync_lock_test_and_set(Target, Value);
+}
+
+static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
+{
+ /* NOTE: ditto */
+ __sync_synchronize();
+ return __sync_lock_test_and_set(Target, Value);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
+{
+ return __sync_fetch_and_add(Addend, Value);
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
+{
+ return __sync_fetch_and_and(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
+{
+ return __sync_fetch_and_and(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
+{
+ return __sync_fetch_and_and(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
+{
+ return __sync_fetch_and_or(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
+{
+ return __sync_fetch_and_or(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
+{
+ return __sync_fetch_and_or(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
+{
+ return __sync_fetch_and_xor(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
+{
+ return __sync_fetch_and_xor(value, mask);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
+{
+ return __sync_fetch_and_xor(value, mask);
+}
+
+#else
+
+static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
+{
+ char retval = Comperand;
+ __asm__ __volatile__ (
+ "sync\n"
+ "1: lbarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " stbcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=b" (retval)
+ : "b" (Destination), "r" (Comperand), "r" (Exchange)
+ : "cr0", "memory");
+ return retval;
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
+{
+ short retval = Comperand;
+ __asm__ __volatile__ (
+ "sync\n"
+ "1: lharx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " sthcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=b" (retval)
+ : "b" (Destination), "r" (Comperand), "r" (Exchange)
+ : "cr0", "memory");
+ return retval;
+}
+
+static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
+{
+ unsigned long lo32Retval = (unsigned long)((Comperand >> 0) & 0xFFFFFFFF);
+ long hi32Retval = (unsigned long)((Comperand >> 32) & 0xFFFFFFFF);
+
+ unsigned long lo32Exchange = (unsigned long)((Exchange >> 0) & 0xFFFFFFFF);
+ long hi32Exchange = (unsigned long)((Exchange >> 32) & 0xFFFFFFFF);
+
+#if 0
+ __asm__
+ (
+ "cmpxchg8b %[Destination]" :
+ "a" (lo32Retval), "d" (hi32Retval) :
+ [Destination] "rm" (Destination), "b" (lo32Exchange), "c" (hi32Exchange) :
+ "memory"
+ );
+#endif
+ {
+ union u_
+ {
+ long long ll;
+ struct s_
+ {
+ unsigned long lo32;
+ long hi32;
+ }
+ s;
+ }
+ u = { s : { lo32 : lo32Retval, hi32 : hi32Retval } };
+
+ return u.ll;
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
+{
+ return (void *)_InterlockedCompareExchange
+ ((long *)Destination, (long) Exchange, (long) Comperand);
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
+{
+ long retval;
+ __asm__ __volatile__ (
+ "sync\n"
+ "1: lwarx %0,0,%1\n"
+ " stwcx. %2,0,%1\n"
+ " bne- 1b\n"
+ : "=b" (retval)
+ : "b" (Target), "b" (Value)
+ : "cr0", "memory");
+ return retval;
+}
+
+static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
+{
+ void * retval;
+ __asm__ __volatile__ (
+ "sync\n"
+ "1: lwarx %0,0,%1\n"
+ " stwcx. %2,0,%1\n"
+ " bne- 1b\n"
+ : "=b" (retval)
+ : "b" (Target), "b" (Value)
+ : "cr0", "memory");
+ return retval;
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
+{
+ long x;
+ long y = *Addend;
+ long addend = y;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange(Addend, addend + Value, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
+{
+ char x;
+ char y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange8(value, x & mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
+{
+ short x;
+ short y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange16(value, x & mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
+{
+ long x;
+ long y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange(value, x & mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
+{
+ char x;
+ char y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange8(value, x | mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
+{
+ short x;
+ short y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange16(value, x | mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
+{
+ long x;
+ long y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange(value, x | mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
+{
+ char x;
+ char y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange8(value, x ^ mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
+{
+ short x;
+ short y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange16(value, x ^ mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
+{
+ long x;
+ long y;
+
+ y = *value;
+
+ do
+ {
+ x = y;
+ y = _InterlockedCompareExchange(value, x ^ mask, x);
+ }
+ while(y != x);
+
+ return y;
+}
+
+static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
+{
+ long x;
+ long y;
+ long mask = ~(1<>= check;
+ *Index += check;
+ }
+ check >>= 1;
+ }
+ return 1;
+ }
+}
+
+/* NOTE: again, the bizarre implementation follows Visual C++ */
+static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b)
+{
+ return ((*a) & (1<> (8-shift));
+}
+
+static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift)
+{
+ return (value << shift) | (value >> (16-shift));
+}
+
+static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift)
+{
+ return (value >> shift) | (value << (8-shift));
+}
+
+static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift)
+{
+ return (value >> shift) | (value << (16-shift));
+}
+
+static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
+{
+ return Mask << Bit;
+}
+
+static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
+{
+ return Mask >> Bit;
+}
+
+static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
+{
+ return Mask >> Bit;
+}
+
+
+/*** 64-bit math ***/
+static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b)
+{
+ return a * b;
+}
+
+static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b)
+{
+ return a * b;
+}
+
+
+/*** Port I/O ***/
+static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port)
+{
+ int ret;
+ __asm__(
+ "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 %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
+ );
+ return ret;
+}
+
+static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port)
+{
+ int ret;
+ __asm__(
+ "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 %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
+ );
+ return ret;
+}
+
+static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port)
+{
+ int ret;
+ __asm__(
+ "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 %0,0(%1)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)
+ );
+ return ret;
+}
+
+static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)
+{
+ while(Count--) {
+ *Buffer++ = __inbyte(Port);
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)
+{
+ while(Count--) {
+ *Buffer++ = __inword(Port);
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)
+{
+ while(Count--) {
+ *Buffer++ = __indword(Port);
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data)
+{
+ __asm__(
+ "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 %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,%1\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t" : : "b" (Port), "r" (Data)
+ );
+}
+
+static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data)
+{
+ __asm__(
+ "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 %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,%1\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t" : : "b" (Port), "b" (Data)
+ );
+}
+
+static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data)
+{
+ __asm__(
+ "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 %1,0(%0)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,%1\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t" : : "b" (Port), "b" (Data)
+ );
+}
+
+static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)
+{
+ unsigned long count = Count;
+ const unsigned char *buffer = Buffer;
+ while(count--) {
+ __outbyte(Port, *buffer++);
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)
+{
+ unsigned long count = Count;
+ const unsigned short *buffer = Buffer;
+ while(count--) {
+ __outword(Port, *buffer++);
+ }
+}
+
+static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)
+{
+ unsigned long count = Count;
+ const unsigned long *buffer = Buffer;
+ while(count--) {
+ __outdword(Port, *buffer++);
+ }
+}
+
+
+/*** System information ***/
+static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType)
+{
+ unsigned long lo32;
+ __asm__("mfpvr" : "=b" (lo32));
+}
+
+static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void)
+{
+ unsigned long lo32;
+ __asm__("mfdec %0" : "=b" (lo32));
+ return -lo32;
+}
+
+
+/*** Interrupts ***/
+/* Finally decided to do this by enabling single step trap */
+static __inline__ __attribute__((always_inline)) void __debugbreak(void)
+{
+
+}
+
+static __inline__ __attribute__((always_inline)) void __int2c(void)
+{
+ /* Not sure yet */
+}
+
+#ifndef _ENABLE_DISABLE_DEFINED
+#define _ENABLE_DISABLE_DEFINED
+static __inline__ __attribute__((always_inline)) void _disable(void)
+{
+ __asm__ __volatile__("mfmsr 0\n\t" \
+ "li 8,0x7fff\n\t" \
+ "and 0,8,0\n\t" \
+ "mtmsr 0\n\t");
+}
+
+static __inline__ __attribute__((always_inline)) void _enable(void)
+{
+ __asm__ __volatile__("mfmsr 0\n\t" \
+ "lis 8,0x8000@ha\n\t" \
+ "or 0,8,0\n\t" \
+ "mtmsr 0\n\t");
+}
+
+/*** Protected memory management ***/
+static __inline__ __attribute__((always_inline)) unsigned long __readsdr1(void)
+{
+ unsigned long value;
+ __asm__("mfsdr1 %0" : "=b" (value));
+ return value;
+}
+
+static __inline__ __attribute__((always_inline)) void __writesdr1(const unsigned long long Data)
+{
+ __asm__("mtsdr1 %0" : : "b" (Data));
+}
+
+/*** System operations ***/
+/* This likely has a different meaning from the X86 equivalent. We'll keep
+ * the name cause it fits */
+static __inline__ __attribute__((always_inline)) unsigned long long __readmsr()
+{
+ unsigned long temp;
+ __asm__("mfmsr %0" : "=b" (temp));
+ return temp;
+}
+
+static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Value)
+{
+ __asm__("mtmsr %0" : : "b" (Value));
+}
+
+/* We'll make sure of the following:
+ * IO operations have completed
+ * Write operations through cache have completed
+ * We've reloaded anything in the data or instruction cache that might have
+ * changed in real ram.
+ */
+static __inline__ __attribute__((always_inline)) void __wbinvd(void)
+{
+ __asm__("eieio\n\t"
+ "dcs\n\t"
+ "sync\n\t"
+ "isync\n\t");
+}
+#endif
+
+static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
+{
+#if 0
+ __asm__
+ (
+ "lock; add %[Value], %[Lo32];"
+ "jae LABEL%=;"
+ "lock; adc $0, %[Hi32];"
+ "LABEL%=:;" :
+ [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) :
+ [Value] "ir" (Value)
+ );
+#endif
+ return Value;
+}
+
+/*** Miscellaneous ***/
+/* BUGBUG: only good for use in macros. Cannot be taken the address of */
+#define __noop(...) ((void)0)
+
+/* TODO: __assume. GCC only supports the weaker __builtin_expect */
+
+#endif
+/* EOF */
diff --git a/reactos/include/psdk/rpc.h b/reactos/include/psdk/rpc.h
index 58f1983fafb..ca4f8a45092 100644
--- a/reactos/include/psdk/rpc.h
+++ b/reactos/include/psdk/rpc.h
@@ -22,7 +22,7 @@
extern "C" {
#endif
-#if defined( MAC ) || defined( _MAC ) || defined(__powerpc__)
+#if defined( MAC ) || defined( _MAC ) || defined(__powerpc__) && !defined(_REACTOS_)
#define __RPC_MAC__
#define __RPC_WIN32__
#include
diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h
index af8a03249f1..62e4a1bc440 100644
--- a/reactos/include/psdk/winnt.h
+++ b/reactos/include/psdk/winnt.h
@@ -4039,6 +4039,7 @@ typedef struct _OBJECT_TYPE_LIST {
#if defined(__GNUC__)
+#ifdef _M_IX86
static __inline__ PVOID GetCurrentFiber(void)
{
void* ret;
@@ -4048,9 +4049,27 @@ static __inline__ PVOID GetCurrentFiber(void)
);
return ret;
}
+#else
+static __inline__ __attribute__((always_inline)) unsigned long __readfsdword_winnt(const unsigned long Offset)
+{
+ unsigned long result;
+ __asm__("\tadd 7,13,%1\n"
+ "\tlwz %0,0(7)\n"
+ : "=r" (result)
+ : "r" (Offset)
+ : "r7");
+ return result;
+}
+
+static __inline__ PVOID GetCurrentFiber(void)
+{
+ return __readfsdword_winnt(0x10);
+}
+#endif
/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */
#ifndef __NTDDK_H
+#ifdef _M_IX86
static __inline__ struct _TEB * NtCurrentTeb(void)
{
struct _TEB *ret;
@@ -4063,6 +4082,12 @@ static __inline__ struct _TEB * NtCurrentTeb(void)
return ret;
}
+#else
+static __inline__ struct _TEB * NtCurrentTeb(void)
+{
+ return __readfsdword_winnt(0x18);
+}
+#endif
#endif
#elif defined(__WATCOMC__)
@@ -4124,12 +4149,36 @@ InterlockedBitTestAndSet(IN LONG volatile *Base,
{
LONG OldBit;
+#ifdef _M_IX86
__asm__ __volatile__("lock "
"btsl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Base)
:"Ir" (Bit)
: "memory");
+#elif defined(_M_PPC)
+ LONG scratch = 0;
+
+ Bit = 1 << Bit;
+ /* %0 - OldBit
+ * %1 - Bit
+ * %2 - scratch
+ * %3 - Base
+ */
+ __asm__ __volatile__(
+ "sync\n"
+ "0:\n\t"
+ "lwarx %2,0,%3\n\t"
+ "mr %0,%2\n\t"
+ "or %2,%1,%2\n\t"
+ "stwcx. %2,0,%3\n\t"
+ "bne- 0b\n\t" :
+ "=r" (OldBit) :
+ "r" (Bit),
+ "r" (scratch),
+ "r" (Base)
+ );
+#endif
return OldBit;
}
@@ -4139,12 +4188,36 @@ InterlockedBitTestAndReset(IN LONG volatile *Base,
{
LONG OldBit;
+#ifdef _M_IX86
__asm__ __volatile__("lock "
"btrl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Base)
:"Ir" (Bit)
: "memory");
+#elif defined(_M_PPC)
+ LONG scratch = 0;
+
+ Bit = ~(1 << Bit);
+ /* %0 - OldBit
+ * %1 - Bit
+ * %2 - scratch
+ * %3 - Base
+ */
+ __asm__ __volatile__(
+ "sync\n"
+ "0:\n\t"
+ "lwarx %2,0,%3\n\t"
+ "mr %0,%2\n\t"
+ "and %2,%1,%2\n\t"
+ "stwcx. %2,0,%3\n\t"
+ "bne- 0b\n\t" :
+ "=r" (OldBit) :
+ "r" (Bit),
+ "r" (scratch),
+ "r" (Base)
+ );
+#endif
return OldBit;
}
@@ -4153,17 +4226,32 @@ BitScanReverse(OUT ULONG *Index,
IN ULONG Mask)
{
BOOLEAN BitPosition = 0;
+#ifdef _M_IX86
__asm__ __volatile__("bsrl %2,%0\n\t"
"setnz %1\n\t"
:"=&r" (*Index), "=r" (BitPosition)
:"rm" (Mask)
:"memory");
return BitPosition;
+#elif defined(_M_PPC)
+ /* Slow implementation for now */
+ for( *Index = 31; *Index; *Index-- ) {
+ if( (1<<*Index) & Mask ) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+#endif
}
#endif
+#ifdef _M_IX86
#define YieldProcessor() __asm__ __volatile__("pause");
+#elif defined(_M_PPC)
+#define YieldProcessor() __asm__ __volatile__("nop");
+#endif
#if defined(_AMD64_)
#if defined(_M_AMD64)
diff --git a/reactos/include/reactos/arc/arc.h b/reactos/include/reactos/arc/arc.h
index 57e2ae05031..43ccdc0e042 100644
--- a/reactos/include/reactos/arc/arc.h
+++ b/reactos/include/reactos/arc/arc.h
@@ -339,6 +339,11 @@ typedef struct _I386_LOADER_BLOCK
ULONG VirtualBias;
} I386_LOADER_BLOCK, *PI386_LOADER_BLOCK;
+typedef struct _PPC_LOADER_BLOCK
+{
+ PVOID BootInfo;
+} PPC_LOADER_BLOCK, *PPPC_LOADER_BLOCK;
+
//
// Loader Parameter Block
//
@@ -369,6 +374,7 @@ typedef struct _LOADER_PARAMETER_BLOCK
I386_LOADER_BLOCK I386;
ALPHA_LOADER_BLOCK Alpha;
IA64_LOADER_BLOCK Ia64;
+ PPC_LOADER_BLOCK PowerPC;
} u;
} LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;
diff --git a/reactos/include/reactos/debug.h b/reactos/include/reactos/debug.h
index 648d77cd788..637527b6420 100644
--- a/reactos/include/reactos/debug.h
+++ b/reactos/include/reactos/debug.h
@@ -126,6 +126,8 @@ RtlAssert(
#define ASM_BREAKPOINT "\nbreak\n"
#elif defined(__x86_64__)
#define ASM_BREAKPOINT "\nint $3\n"
+#elif defined(_M_PPC)
+#define ASM_BREAKPOINT "\ntwi 1\n"
#else
#error Unsupported architecture.
#endif
diff --git a/reactos/include/reactos/elf/elf-powerpc.h b/reactos/include/reactos/elf/elf-powerpc.h
new file mode 100644
index 00000000000..6365df86fdf
--- /dev/null
+++ b/reactos/include/reactos/elf/elf-powerpc.h
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
+ */
+
+#ifndef _MACHINE_ELF_H_
+#define _MACHINE_ELF_H_ 1
+
+/*
+ * ELF definitions for the powerpc architecture.
+ */
+
+#ifdef _REACTOS_ELF_MACHINE_IS_TARGET
+
+#ifndef __ELF_WORD_SIZE
+#define __ELF_WORD_SIZE 32 /* Used by */
+#endif
+
+#include
+
+#define ELF_ARCH EM_386
+
+#define ELF_MACHINE_OK(x) ((x) == EM_386 || (x) == EM_486)
+
+/*
+ * Auxiliary vector entries for passing information to the interpreter.
+ *
+ * The powerpc supplement to the SVR4 ABI specification names this "auxv_t",
+ * but POSIX lays claim to all symbols ending with "_t".
+ */
+
+typedef struct { /* Auxiliary vector entry on initial stack */
+ int a_type; /* Entry type. */
+ union {
+ long a_val; /* Integer value. */
+ void *a_ptr; /* Address. */
+ void (*a_fcn)(void); /* Function pointer (not used). */
+ } a_un;
+} Elf32_Auxinfo;
+
+#if __ELF_WORD_SIZE == 64
+/* Fake for amd64 loader support */
+typedef struct {
+ int fake;
+} Elf64_Auxinfo;
+#endif
+
+__ElfType(Auxinfo);
+
+/* Values for a_type. */
+#define AT_NULL 0 /* Terminates the vector. */
+#define AT_IGNORE 1 /* Ignored entry. */
+#define AT_EXECFD 2 /* File descriptor of program to load. */
+#define AT_PHDR 3 /* Program header of program already loaded. */
+#define AT_PHENT 4 /* Size of each program header entry. */
+#define AT_PHNUM 5 /* Number of program header entries. */
+#define AT_PAGESZ 6 /* Page size in bytes. */
+#define AT_BASE 7 /* Interpreter's base address. */
+#define AT_FLAGS 8 /* Flags (unused for powerpc). */
+#define AT_ENTRY 9 /* Where interpreter should transfer control. */
+
+/*
+ * The following non-standard values are used for passing information
+ * from John Polstra's testbed program to the dynamic linker. These
+ * are expected to go away soon.
+ *
+ * Unfortunately, these overlap the Linux non-standard values, so they
+ * must not be used in the same context.
+ */
+#define AT_BRK 10 /* Starting point for sbrk and brk. */
+#define AT_DEBUG 11 /* Debugging level. */
+
+/*
+ * The following non-standard values are used in Linux ELF binaries.
+ */
+#define AT_NOTELF 10 /* Program is not ELF ?? */
+#define AT_UID 11 /* Real uid. */
+#define AT_EUID 12 /* Effective uid. */
+#define AT_GID 13 /* Real gid. */
+#define AT_EGID 14 /* Effective gid. */
+
+#define AT_COUNT 15 /* Count of defined aux entry types. */
+
+/* Define "machine" characteristics */
+#define ELF_TARG_CLASS ELFCLASS32
+#define ELF_TARG_DATA ELFDATA2LSB
+#define ELF_TARG_MACH EM_386
+#define ELF_TARG_VER 1
+
+#endif /* _REACTOS_ELF_MACHINE_IS_TARGET */
+
+/*
+ * Relocation types.
+ */
+
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+#define R_PPC_COUNT 37
+
+#endif /* !_MACHINE_ELF_H_ */
diff --git a/reactos/include/reactos/elf/machine.h b/reactos/include/reactos/elf/machine.h
index 27d7e494ebd..a570b1c4adf 100644
--- a/reactos/include/reactos/elf/machine.h
+++ b/reactos/include/reactos/elf/machine.h
@@ -5,6 +5,10 @@
#define _REACTOS_ELF_MACHINE_IS_TARGET
#include
#undef _REACTOS_ELF_MACHINE_IS_TARGET
+#elif defined(_M_PPC)
+#define _REACTOS_ELF_MACHINE_IS_TARGET
+#include
+#undef _REACTOS_ELF_MACHINE_IS_TARGET
#else
#error Unsupported target architecture
#endif
diff --git a/reactos/include/reactos/elf/reactos.h b/reactos/include/reactos/elf/reactos.h
new file mode 100644
index 00000000000..00743db9fa1
--- /dev/null
+++ b/reactos/include/reactos/elf/reactos.h
@@ -0,0 +1,7 @@
+#ifndef _SYS_ELF_REACTOS_H_
+#define _SYS_ELF_REACTOS_H_ 1
+
+#define TYPE_PEHEADER (SHT_LOOS+1)
+#define ADDR24_MASK 0x03fffffc
+
+#endif/*_SYS_ELF_REACTOS_H_*/
diff --git a/reactos/include/reactos/libs/ppcmmu/mmu.h b/reactos/include/reactos/libs/ppcmmu/mmu.h
new file mode 100644
index 00000000000..00e32d5ee0d
--- /dev/null
+++ b/reactos/include/reactos/libs/ppcmmu/mmu.h
@@ -0,0 +1,228 @@
+#ifndef PPCMMU_H
+#define PPCMMU_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:
+ * 00 -- Initialize
+ * -- No arguments
+ * 01 -- Map page
+ * r4 -- virtual address
+ * r5 -- ppc_map_info_t
+ * 02 -- Erase page
+ * r4 -- virtual address
+ * 03 -- Set segment VSID
+ * r4 -- Start seg
+ * r5 -- End seg
+ * r6 -- Vsid
+ * 04 -- Set page miss callback
+ * r4 -- Callback address (VA)
+ * 05 -- Query page
+ * r4 -- Page addr
+ * r5 -- Address of info struct
+ * 06 -- Unit Test
+ * 07 -- Turn on paging
+ * 08 -- Unmap process
+ */
+
+#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 lr, cr, ctr, srr0, srr1, dsisr, dar, xer;
+} ppc_trap_frame_t;
+
+typedef int (*MmuPageCallback)(int inst, 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, oldbat[8], 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 && gotbat < 2; i++)
+ {
+ GetBat(i, 1, &batu, &batl);
+ 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;
+ }
+ }
+
+ GetBat(usebat[0], 0, &oldbat[0], &oldbat[1]);
+ GetBat(usebat[0], 1, &oldbat[2], &oldbat[3]);
+ GetBat(usebat[1], 0, &oldbat[4], &oldbat[5]);
+ GetBat(usebat[1], 1, &oldbat[6], &oldbat[7]);
+
+ 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);
+
+ /* Ok done ... Whatever happened probably worked */
+ SetBat(usebat[0], 0, oldbat[0], oldbat[1]);
+ SetBat(usebat[0], 1, oldbat[2], oldbat[3]);
+ SetBat(usebat[1], 0, oldbat[4], oldbat[5]);
+ SetBat(usebat[1], 1, oldbat[6], oldbat[7]);
+
+ 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;
+ int *start = (int *)_start;
+ while(start < (int *)_end)
+ {
+ SetPhys(target, *start++);
+ target += sizeof(int);
+ }
+ PPCMMU(0, 0, 0, 0);
+}
+
+static inline void MmuMapPage(ppc_map_info_t *info, int count)
+{
+ PPCMMU(1, info, (void *)count, 0);
+}
+
+static inline void MmuUnmapPage(ppc_map_info_t *info, int count)
+{
+ PPCMMU(2, info, (void *)count, 0);
+}
+
+static inline void MmuSetVsid(int start, int end, int vsid)
+{
+ PPCMMU(3, (void *)start, (void *)end, (void *)vsid);
+}
+
+static inline MmuPageCallback MmuSetPageCallback(MmuPageCallback cb)
+{
+ return (MmuPageCallback)PPCMMU(4, (void *)cb, 0, 0);
+}
+
+static inline void MmuInqPage(ppc_map_info_t *info, int count)
+{
+ PPCMMU(5, info, (void *)count, 0);
+}
+
+static inline int MmuUnitTest()
+{
+ return PPCMMU(6, 0, 0, 0);
+}
+
+static inline int MmuTurnOn(void *fun, void *arg)
+{
+ return PPCMMU(7, fun, arg, 0);
+}
+
+static inline void MmuSetMemorySize(paddr_t size)
+{
+ PPCMMU(8, (void *)size, 0, 0);
+}
+
+static inline paddr_t MmuGetFirstPage()
+{
+ return (paddr_t)PPCMMU(9, 0, 0, 0);
+}
+
+static inline void *MmuAllocVsid(int vsid, int mask)
+{
+ return (void *)PPCMMU(10, (void *)vsid, (void *)mask, 0);
+}
+
+static inline void MmuRevokeVsid(int vsid, int mask)
+{
+ PPCMMU(11, (void *)vsid, (void *)mask, 0);
+}
+
+#endif/*PPCMMU_H*/
diff --git a/reactos/include/reactos/libs/ppcmmu/mmuutil.h b/reactos/include/reactos/libs/ppcmmu/mmuutil.h
new file mode 100644
index 00000000000..9528b571fc4
--- /dev/null
+++ b/reactos/include/reactos/libs/ppcmmu/mmuutil.h
@@ -0,0 +1,23 @@
+#ifndef FREELDR_MMU_H
+#define FREELDR_MMU_H
+
+int GetDEC();
+int GetMSR();
+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 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*/
diff --git a/reactos/include/reactos/ppcboot.h b/reactos/include/reactos/ppcboot.h
new file mode 100644
index 00000000000..8dc39c24bf8
--- /dev/null
+++ b/reactos/include/reactos/ppcboot.h
@@ -0,0 +1,14 @@
+#ifndef REACTOS_PPCBOOT_H
+#define REACTOS_PPCBOOT_H
+
+typedef char font_char[57];
+typedef struct _boot_infos_t {
+ void *loaderBlock;
+ int dispDeviceRect[4];
+ int dispDeviceRowBytes;
+ int dispDeviceDepth;
+ void *dispDeviceBase;
+ font_char *dispFont;
+} boot_infos_t;
+
+#endif/*REACTOS_PPCBOOT_H*/
diff --git a/reactos/include/reactos/ppcdebug.h b/reactos/include/reactos/ppcdebug.h
new file mode 100644
index 00000000000..0b665a3c158
--- /dev/null
+++ b/reactos/include/reactos/ppcdebug.h
@@ -0,0 +1,20 @@
+#ifndef _PPCDEBUG_H
+#define _PPCDEBUG_H
+
+#include "ppcboot.h"
+
+extern struct _boot_infos_t *BootInfo;
+extern void DrawNumber(struct _boot_infos_t *, unsigned long, int, int);
+extern void DrawString(struct _boot_infos_t *, const char *, int, int);
+#define TRACEXY(x,y) do { \
+ unsigned long _x_ = (unsigned long)(x), _y_ = (unsigned long)(y); \
+ __asm__("ori 0,0,0"); \
+ DrawNumber(BootInfo, __LINE__, 10, 160); \
+ DrawString(BootInfo, __FILE__, 100, 160); \
+ DrawNumber(BootInfo, _x_, 400, 160); \
+ DrawNumber(BootInfo, _y_, 490, 160); \
+} while(0)
+#define TRACEX(x) TRACEXY(x,0)
+#define TRACE TRACEX(0)
+
+#endif//_PPCDEBUG_H
diff --git a/reactos/include/reactos/ppcfont.h b/reactos/include/reactos/ppcfont.h
new file mode 100644
index 00000000000..4ea53e74862
--- /dev/null
+++ b/reactos/include/reactos/ppcfont.h
@@ -0,0 +1,259 @@
+#ifndef _ARCH_POWERPC_FONT_H
+#define _ARCH_POWERPC_FONT_H
+
+font_char BootDigits[37] = {
+ " XXXXX "
+ "X X "
+ "X x X "
+ "X X X "
+ "X X "
+ " XXXXX "
+ " ",
+ " XX "
+ " XXX "
+ " XX "
+ " XX "
+ " XX "
+ " XX "
+ " ",
+ " XXXX "
+ " X X "
+ " XX "
+ " XX "
+ " XX "
+ " XXXXXX "
+ " ",
+ " XXXX "
+ " X X "
+ " XX "
+ " X "
+ " X X "
+ " XXXX "
+ " ",
+ " X X "
+ " X X "
+ " XXXXXX "
+ " X "
+ " X "
+ " X "
+ " ",
+ " XXXXXX "
+ " X "
+ " XXXXX "
+ " X "
+ " X "
+ " XXXXX "
+ " ",
+ " XXXXX "
+ " X "
+ " XXXXX "
+ " X X "
+ " X X "
+ " XXXX "
+ " ",
+ " XXXXXX "
+ " XX "
+ " XX "
+ " XXXXX "
+ " XX "
+ " XX "
+ " ",
+ " XXXX "
+ " X X "
+ " XXXX "
+ " X X "
+ " X X "
+ " XXXX "
+ " ",
+ " XXXX "
+ " X X "
+ " X X "
+ " XXXXX "
+ " X "
+ " XXXX "
+ " ",
+ " XXXX "
+ " X X "
+ " XXXXXX "
+ " X X "
+ " X X "
+ " X X "
+ " ",
+ " XXXXX "
+ " X X "
+ " XXXXX "
+ " X X "
+ " X X "
+ " XXXXX "
+ " ",
+ " XXXX "
+ " X X "
+ " X "
+ " X "
+ " X X "
+ " XXXX "
+ " ",
+ " XXXXX "
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " XXXXX "
+ " ",
+ " XXXXXX "
+ " X "
+ " XXXX "
+ " X "
+ " X "
+ " XXXXXX "
+ " ",
+ " XXXXXX "
+ " X "
+ " XXXX "
+ " X "
+ " X "
+ " X "
+ " ",
+ " XXXX "
+ " X X "
+ " X "
+ " X XX "
+ " X X "
+ " XXXXX "
+ " ",
+ " X X "
+ " X X "
+ " XXXXXX "
+ " X X "
+ " X X "
+ " X X "
+ " ",
+ " XXXX "
+ " XX "
+ " XX "
+ " XX "
+ " XX "
+ " XXXX "
+ " ",
+ " X "
+ " X "
+ " X "
+ " X "
+ " X X "
+ " XXXX "
+ " ",
+ " X X "
+ " X X "
+ " X X "
+ " XXXX "
+ " X X "
+ " X X "
+ " ",
+ " X "
+ " X "
+ " X "
+ " X "
+ " X "
+ " XXXXXX "
+ " ",
+ " X X "
+ " X XX X "
+ " X XX X "
+ " X X "
+ " X X "
+ " X X "
+ " ",
+ " X X "
+ " XX X "
+ " X X X "
+ " X X X "
+ " X XX "
+ " X X "
+ " ",
+ " XXXX "
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " XXXX "
+ " ",
+ " XXXXX "
+ " X X "
+ " X X "
+ " XXXXX "
+ " X "
+ " X "
+ " ",
+ " XXXX "
+ " X X "
+ " X X "
+ " X X X "
+ " X XXX "
+ " XXXXX "
+ " ",
+ " XXXXX "
+ " X X "
+ " X X "
+ " XXXXX "
+ " X X "
+ " X X "
+ " ",
+ " XXXXX "
+ " X "
+ " XXXX "
+ " X "
+ " X "
+ " XXXXX "
+ " ",
+ " XXXXXX "
+ " XX "
+ " XX "
+ " XX "
+ " XX "
+ " XX "
+ " ",
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " XXXX "
+ " ",
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " X X "
+ " XX "
+ " ",
+ " X X "
+ " X X "
+ " X X "
+ " X XX X "
+ " X XX X "
+ " X X "
+ " ",
+ " X X "
+ " X X "
+ " XX "
+ " X X "
+ " X X "
+ " X X "
+ " ",
+ " X X "
+ " X X "
+ " X X "
+ " XX "
+ " XX "
+ " XX "
+ " ",
+ " XXXXXX "
+ " X "
+ " X "
+ " X "
+ " X "
+ " XXXXXX "
+ " "
+};
+
+#endif/*_ARCH_POWERPC_FONT_H*/
diff --git a/reactos/include/reactos/rosldr.h b/reactos/include/reactos/rosldr.h
index 65285698ec0..fbbd187edf3 100644
--- a/reactos/include/reactos/rosldr.h
+++ b/reactos/include/reactos/rosldr.h
@@ -42,6 +42,7 @@ typedef struct _ROS_LOADER_PARAMETER_BLOCK
ULONG PageDirectoryStart;
ULONG PageDirectoryEnd;
ULONG KernelBase;
+ ULONG ArchExtra;
} ROS_LOADER_PARAMETER_BLOCK, *PROS_LOADER_PARAMETER_BLOCK;
extern ULONG MmFreeLdrMemHigher, MmFreeLdrMemLower;
diff --git a/reactos/lib/rtl/exception.c b/reactos/lib/rtl/exception.c
index 62f5a8c64d5..5a110f93541 100644
--- a/reactos/lib/rtl/exception.c
+++ b/reactos/lib/rtl/exception.c
@@ -137,6 +137,8 @@ RtlWalkFrameChain(OUT PVOID *Callers,
#endif
#elif defined(_M_MIPS)
__asm__("move $sp, %0" : "=r" (Stack) : );
+#elif defined(_M_PPC)
+ __asm__("mr %0,1" : "=r" (Stack) : );
#else
#error Unknown architecture
#endif
diff --git a/reactos/lib/rtl/powerpc/debug.c b/reactos/lib/rtl/powerpc/debug.c
new file mode 100644
index 00000000000..984f33785a7
--- /dev/null
+++ b/reactos/lib/rtl/powerpc/debug.c
@@ -0,0 +1,42 @@
+#include
+#include
+
+NTKERNELAPI
+VOID
+DbgBreakPoint() { __asm__("ti 31,0,0"); }
+
+NTKERNELAPI
+VOID
+DbgBreakPointWithStatus(ULONG Status) { __asm__("ti 31,0,0"); }
+
+NTSTATUS
+NTAPI
+DebugService
+(ULONG Service, const void *Buffer, ULONG Length, PVOID Arg1, PVOID Arg2)
+{
+ NTSTATUS Result;
+ __asm__("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"
+ "mr 8,%1\n\t"
+ "sc\n\t"
+ "mr %0,3\n\t" :
+ "=r" (Result) :
+ "r" (0x10000),
+ "r" (Service),
+ "r" (Buffer),
+ "r" (Length),
+ "r" (Arg1),
+ "r" (Arg2) );
+ return Result;
+}
+
+NTSTATUS
+NTAPI
+DebugService2
+(PVOID Arg1, PVOID Arg2, ULONG Service)
+{
+ return STATUS_SUCCESS;
+}
diff --git a/reactos/lib/rtl/powerpc/except.c b/reactos/lib/rtl/powerpc/except.c
new file mode 100644
index 00000000000..5b6bce3397d
--- /dev/null
+++ b/reactos/lib/rtl/powerpc/except.c
@@ -0,0 +1,62 @@
+/* COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Runtime Library
+ * PURPOSE: User-Mode Exception Support
+ * FILE: lib/rtl/exception.c
+ * PROGRAMERS: Alex Ionescu (alex@relsoft.net)
+ * David Welch
+ * Skywing
+ * KJK::Hyperion
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+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;
+}
+
+NTSYSAPI
+PVOID
+RtlpGetExceptionAddress()
+{
+ // XXX arty fixme
+ return NULL;
+}
+
+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)
+{
+}
diff --git a/reactos/lib/rtl/powerpc/interlocked.c b/reactos/lib/rtl/powerpc/interlocked.c
new file mode 100644
index 00000000000..b681b2e3e4d
--- /dev/null
+++ b/reactos/lib/rtl/powerpc/interlocked.c
@@ -0,0 +1,124 @@
+typedef unsigned int size_t;
+#include
+#include
+#include
+#include
+
+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;
+}
diff --git a/reactos/lib/rtl/powerpc/thread.c b/reactos/lib/rtl/powerpc/thread.c
new file mode 100644
index 00000000000..b7a3204798e
--- /dev/null
+++ b/reactos/lib/rtl/powerpc/thread.c
@@ -0,0 +1,38 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * PURPOSE: Rtl user thread functions
+ * FILE: lib/rtl/thread.c
+ * PROGRAMERS:
+ * Alex Ionescu (alex@relsoft.net)
+ * Eric Kohl
+ * KJK::Hyperion
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "i386/ketypes.h"
+
+#define NDEBUG
+#include
+
+/* 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 */
diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild
index ce69b56a61d..9ff60fa5762 100644
--- a/reactos/lib/rtl/rtl.rbuild
+++ b/reactos/lib/rtl/rtl.rbuild
@@ -18,6 +18,14 @@
thread.c
+
+
+ debug.c
+ except.c
+ interlocked.c
+ thread.c
+
+
avl.c
tree.c
diff --git a/reactos/ntoskrnl/include/internal/powerpc/intrin_i.h b/reactos/ntoskrnl/include/internal/powerpc/intrin_i.h
new file mode 100644
index 00000000000..c5ba0381421
--- /dev/null
+++ b/reactos/ntoskrnl/include/internal/powerpc/intrin_i.h
@@ -0,0 +1,6 @@
+#ifndef _INTRIN_INTERNAL_
+#define _INTRIN_INTERNAL_
+
+#endif
+
+/* EOF */
diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
index 45db6e03a8e..8ef64ee20cf 100644
--- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
+++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
@@ -146,7 +146,7 @@ MingwModuleHandler::PassThruCacheDirectory (const FileLocation* fileLocation )
MingwModuleHandler::GetTargetDirectoryTree (
const Module& module )
{
- if ( module.type == StaticLibrary )
+ if ( module.type == StaticLibrary || module.type == BootProgram )
return backend->intermediateDirectory;
return backend->outputDirectory;
}
@@ -267,6 +267,9 @@ MingwModuleHandler::InstanciateHandler (
case EmbeddedTypeLib:
handler = new MingwEmbeddedTypeLibModuleHandler ( module );
break;
+ case ElfExecutable:
+ handler = new MingwElfExecutableModuleHandler ( module );
+ break;
default:
throw UnknownModuleTypeException (
module.node.location,
@@ -3145,20 +3148,24 @@ MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
- fprintf ( fMakefile, "\t$(BOOTPROG_PREPARE) $(OUTPUT)$(SEP)%s %s\n",
+ fprintf ( fMakefile, "\t$(%s_PREPARE) $(OUTPUT)$(SEP)%s %s\n",
+ module.buildtype.c_str (),
NormalizeFilename( payload->GetPath() ).c_str (),
junk_cpy.c_str () );
- fprintf ( fMakefile, "\t${objcopy} $(BOOTPROG_FLATFORMAT) %s %s\n",
+ fprintf ( fMakefile, "\t${objcopy} $(%s_FLATFORMAT) %s %s\n",
+ module.buildtype.c_str (),
junk_cpy.c_str (),
junk_tmp.c_str () );
- fprintf ( fMakefile, "\t${ld} $(BOOTPROG_LINKFORMAT) %s %s -g -o %s\n",
+ fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
+ module.buildtype.c_str (),
linkDepsMacro.c_str (),
junk_tmp.c_str (),
junk_elf.c_str () );
- fprintf ( fMakefile, "\t${objcopy} $(BOOTPROG_COPYFORMAT) %s %s\n",
+ fprintf ( fMakefile, "\t${objcopy} $(%s_COPYFORMAT) %s $(INTERMEDIATE)$(SEP)%s\n",
+ module.buildtype.c_str (),
junk_elf.c_str (),
module.GetPath().c_str () );
@@ -3690,3 +3697,37 @@ MingwIdlHeaderModuleHandler::Process ()
{
GenerateRules ();
}
+
+MingwElfExecutableModuleHandler::MingwElfExecutableModuleHandler (
+ const Module& module_ )
+
+ : MingwModuleHandler ( module_ )
+{
+}
+
+void
+MingwElfExecutableModuleHandler::Process ()
+{
+ string targetName ( module.GetTargetName () );
+ string targetMacro ( GetTargetMacro (module) );
+ string workingDirectory = GetWorkingDirectory ();
+ string objectsMacro = GetObjectsMacro ( module );
+ string linkDepsMacro = GetLinkingDependenciesMacro ();
+ string libsMacro = GetLibsMacro ();
+
+ GenerateRules ();
+
+ fprintf ( fMakefile, "%s: %s %s | %s\n",
+ targetMacro.c_str (),
+ objectsMacro.c_str (),
+ linkDepsMacro.c_str (),
+ GetDirectory(GetTargetFilename(module,NULL)).c_str () );
+
+ fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
+
+ fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
+ module.buildtype.c_str(),
+ objectsMacro.c_str(),
+ libsMacro.c_str(),
+ targetMacro.c_str () );
+}
diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h
index 804c4e26ad4..e68f858b6c5 100644
--- a/reactos/tools/rbuild/backend/mingw/modulehandler.h
+++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h
@@ -125,6 +125,7 @@ protected:
void GenerateRules ();
void GenerateImportLibraryTargetIfNeeded ();
void GetDefinitionDependencies ( string_list& dependencies ) const;
+
std::string GetLinkingDependencies () const;
static MingwBackend* backend;
static FILE* fMakefile;
@@ -514,4 +515,12 @@ public:
virtual void Process ();
};
+class MingwElfExecutableModuleHandler : public MingwModuleHandler
+{
+public:
+ MingwElfExecutableModuleHandler ( const Module& module );
+ virtual HostType DefaultHost() { return HostFalse; }
+ virtual void Process ();
+};
+
#endif /* MINGW_MODULEHANDLER_H */
diff --git a/reactos/tools/rbuild/bootstrap.cpp b/reactos/tools/rbuild/bootstrap.cpp
index 32127a3ab5d..e01303db139 100644
--- a/reactos/tools/rbuild/bootstrap.cpp
+++ b/reactos/tools/rbuild/bootstrap.cpp
@@ -68,6 +68,7 @@ Bootstrap::IsSupportedModuleType ( ModuleType type )
case Alias:
case IdlHeader:
case EmbeddedTypeLib:
+ case ElfExecutable:
return false;
}
throw InvalidOperationException ( __FILE__,
diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp
index 910c9ef6e48..7cd17984eb9 100644
--- a/reactos/tools/rbuild/module.cpp
+++ b/reactos/tools/rbuild/module.cpp
@@ -474,6 +474,19 @@ Module::Module ( const Project& project,
att = moduleNode.GetAttribute ( "payload", true );
payload = att->value;
}
+
+ if ( type == BootProgram || type == ElfExecutable )
+ {
+ att = moduleNode.GetAttribute ( "buildtype", false );
+ if ( att != NULL )
+ {
+ buildtype = att->value;
+ }
+ else
+ {
+ buildtype = "BOOTPROG";
+ }
+ }
}
Module::~Module ()
@@ -879,6 +892,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
return IdlHeader;
if ( attribute.value == "embeddedtypelib" )
return EmbeddedTypeLib;
+ if ( attribute.value == "elfexecutable" )
+ return ElfExecutable;
throw InvalidAttributeValueException ( location,
attribute.name,
attribute.value );
@@ -891,6 +906,7 @@ Module::GetDefaultModuleExtension () const
{
case BuildTool:
return ExePostfix;
+ case BootProgram:
case StaticLibrary:
return ".a";
case ObjectLibrary:
@@ -926,7 +942,7 @@ Module::GetDefaultModuleExtension () const
case RpcClient:
return ".o";
case Alias:
- case BootProgram:
+ case ElfExecutable:
case IdlHeader:
return "";
case EmbeddedTypeLib:
@@ -979,6 +995,7 @@ Module::GetDefaultModuleEntrypoint () const
case Alias:
case BootProgram:
case IdlHeader:
+ case ElfExecutable:
case EmbeddedTypeLib:
return "";
}
@@ -1007,6 +1024,8 @@ Module::GetDefaultModuleBaseaddress () const
case KernelModeDLL:
case KernelModeDriver:
return "0x00010000";
+ case ElfExecutable:
+ return "0xe00000";
case BuildTool:
case StaticLibrary:
case ObjectLibrary:
@@ -1066,6 +1085,7 @@ Module::IsDLL () const
case Alias:
case IdlHeader:
case EmbeddedTypeLib:
+ case ElfExecutable:
return false;
}
throw InvalidOperationException ( __FILE__,
@@ -1091,18 +1111,19 @@ Module::GenerateInOutputTree () const
case BuildTool:
case BootLoader:
case BootSector:
- case BootProgram:
case Iso:
case LiveIso:
case IsoRegTest:
case LiveIsoRegTest:
case EmbeddedTypeLib:
+ case ElfExecutable:
return true;
case StaticLibrary:
case ObjectLibrary:
case RpcServer:
case RpcClient:
case Alias:
+ case BootProgram:
case IdlHeader:
return false;
}
@@ -1686,6 +1707,7 @@ AutoRegister::IsSupportedModuleType ( ModuleType type )
case Alias:
case IdlHeader:
case EmbeddedTypeLib:
+ case ElfExecutable:
return false;
}
throw InvalidOperationException ( __FILE__,
diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h
index 19cb51cc742..b5d8a13fae8 100644
--- a/reactos/tools/rbuild/rbuild.h
+++ b/reactos/tools/rbuild/rbuild.h
@@ -274,7 +274,8 @@ enum ModuleType
IdlHeader = 23,
IsoRegTest = 24,
LiveIsoRegTest = 25,
- EmbeddedTypeLib = 26
+ EmbeddedTypeLib = 26,
+ ElfExecutable = 27
};
enum HostType
@@ -295,6 +296,7 @@ public:
std::string extension;
std::string baseaddress;
std::string payload;
+ std::string buildtype;
std::string path;
ModuleType type;
ImportLibrary* importLibrary;