mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 12:23:28 +00:00
[HAL]
Add some files for amd64, just enough to make compilation start. svn path=/trunk/; revision=46455
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 <reactos/asm.h>
|
||||
#include <ndk/amd64/asm.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
.data
|
||||
|
||||
.global MsgUnimplemented
|
||||
MsgUnimplemented:
|
||||
.asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
.text
|
||||
.code64
|
||||
|
||||
PUBLIC HalpCalibrateStallExecution@0
|
||||
HalpCalibrateStallExecution@0:
|
||||
|
||||
|
||||
PUBLIC HalpProfileInterrupt
|
||||
HalpProfileInterrupt:
|
||||
|
||||
|
||||
PUBLIC KeStallExecutionProcessor
|
||||
KeStallExecutionProcessor:
|
||||
|
||||
/* Get the number of microseconds required */
|
||||
jecxz Done
|
||||
|
||||
/* Multiply by the stall factor */
|
||||
mov eax, gs:[KPCR_STALL_SCALE_FACTOR]
|
||||
mul ecx
|
||||
|
||||
/* Align to 16 bytes */
|
||||
.align 16
|
||||
|
||||
/* Jump to subtraction loop */
|
||||
jmp SubtractLoop
|
||||
|
||||
/* Align to 16 bytes */
|
||||
.align 16
|
||||
|
||||
/* Subtract one count */
|
||||
SubtractLoop:
|
||||
sub eax, 1
|
||||
jnz SubtractLoop
|
||||
|
||||
Done:
|
||||
/* Return */
|
||||
ret 4
|
||||
|
||||
|
||||
PUBLIC HalpQuery8254Counter
|
||||
HalpQuery8254Counter:
|
||||
|
||||
/* Save EFLAGS and disable interrupts */
|
||||
pushfq
|
||||
cli
|
||||
|
||||
/* Set timer data */
|
||||
mov al, 0
|
||||
out 0x43, al
|
||||
jmp $+2
|
||||
|
||||
/* Read current timer */
|
||||
in al, 0x40
|
||||
jmp $+2
|
||||
movzx ecx, al
|
||||
in al, 0x40
|
||||
mov ch, al
|
||||
|
||||
/* Return it and restore interrupt state */
|
||||
mov eax, ecx
|
||||
popfq
|
||||
ret
|
||||
|
||||
PUBLIC HalpClockInterrupt
|
||||
HalpClockInterrupt:
|
||||
UNIMPLEMENTED _HalpClockInterrupt
|
||||
iret
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: GPL, See COPYING in the top level directory
|
||||
* FILE: hal/halx86/generic/amd64/x86bios.c
|
||||
* PURPOSE:
|
||||
* PROGRAMMERS: Timo Kreuzer ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "x86emu.h"
|
||||
|
||||
/* This page serves as fallback for pages used by Mm */
|
||||
#define DEFAULT_PAGE 0x21
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
BOOLEAN x86BiosIsInitialized;
|
||||
LONG x86BiosBufferIsAllocated = 0;
|
||||
PUCHAR x86BiosMemoryMapping;
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgDumpPage(PUCHAR MemBuffer, USHORT Segment)
|
||||
{
|
||||
ULONG x, y, Offset;
|
||||
|
||||
for (y = 0; y < 0x100; y++)
|
||||
{
|
||||
for (x = 0; x < 0x10; x++)
|
||||
{
|
||||
Offset = Segment * 16 + y * 16 + x;
|
||||
DbgPrint("%02x ", MemBuffer[Offset]);
|
||||
}
|
||||
DbgPrint("\n");
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
PPFN_NUMBER PfnArray;
|
||||
PFN_NUMBER Pfn, Last;
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
|
||||
PLIST_ENTRY ListEntry;
|
||||
PMDL Mdl;
|
||||
|
||||
/* Allocate an MDL for 1MB */
|
||||
Mdl = IoAllocateMdl(NULL, 0x100000, FALSE, FALSE, NULL);
|
||||
if (!Mdl)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/* Get pointer to the pfn array */
|
||||
PfnArray = MmGetMdlPfnArray(Mdl);
|
||||
|
||||
/* Fill the array with low memory PFNs */
|
||||
for (Pfn = 0; Pfn < 0x100; Pfn++)
|
||||
{
|
||||
PfnArray[Pfn] = Pfn;
|
||||
}
|
||||
|
||||
/* Loop the memory descriptors */
|
||||
for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||||
ListEntry != &LoaderBlock->MemoryDescriptorListHead;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
/* Get the memory descriptor */
|
||||
Descriptor = CONTAINING_RECORD(ListEntry,
|
||||
MEMORY_ALLOCATION_DESCRIPTOR,
|
||||
ListEntry);
|
||||
|
||||
/* Check if the memory is in the low range */
|
||||
if (Descriptor->BasePage < 0x100)
|
||||
{
|
||||
/* Check if the memory type is firmware */
|
||||
if (Descriptor->MemoryType != LoaderFirmwarePermanent &&
|
||||
Descriptor->MemoryType != LoaderSpecialMemory)
|
||||
{
|
||||
/* It's something else, so don't use it! */
|
||||
Last = min(Descriptor->BasePage + Descriptor->PageCount, 0x100);
|
||||
for (Pfn = Descriptor->BasePage; Pfn < Last; Pfn++)
|
||||
{
|
||||
/* Set each page to the default page */
|
||||
PfnArray[Pfn] = DEFAULT_PAGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mdl->MdlFlags = MDL_PAGES_LOCKED;
|
||||
|
||||
/* Map the MDL to system space */
|
||||
x86BiosMemoryMapping = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
|
||||
ASSERT(x86BiosMemoryMapping);
|
||||
|
||||
DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8));
|
||||
//DbgDumpPage(x86BiosMemoryMapping, 0xc351);
|
||||
|
||||
x86BiosIsInitialized = TRUE;
|
||||
|
||||
HalpBiosDisplayReset();
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
x86BiosAllocateBuffer(
|
||||
ULONG *Size,
|
||||
USHORT *Segment,
|
||||
USHORT *Offset)
|
||||
{
|
||||
/* Check if the system is initialized and the buffer is large enough */
|
||||
if (!x86BiosIsInitialized || *Size > PAGE_SIZE)
|
||||
{
|
||||
/* Something was wrong, fail! */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check if the buffer is already allocated */
|
||||
if (InterlockedBitTestAndSet(&x86BiosBufferIsAllocated, 0))
|
||||
{
|
||||
/* Buffer was already allocated, fail */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* The buffer is sufficient, return hardcoded address and size */
|
||||
*Size = PAGE_SIZE;
|
||||
*Segment = 0x2000;
|
||||
*Offset = 0;
|
||||
|
||||
return STATUS_SUCCESS;;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
x86BiosFreeBuffer(
|
||||
USHORT Segment,
|
||||
USHORT Offset)
|
||||
{
|
||||
/* Check if the system is initialized and if the address matches */
|
||||
if (!x86BiosIsInitialized || Segment != 0x2000 || Offset != 0)
|
||||
{
|
||||
/* Something was wrong, fail */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if the buffer was allocated */
|
||||
if (!InterlockedBitTestAndReset(&x86BiosBufferIsAllocated, 0))
|
||||
{
|
||||
/* It was not, fail */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Buffer is freed, nothing more to do */
|
||||
return STATUS_SUCCESS;;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
x86BiosReadMemory(
|
||||
USHORT Segment,
|
||||
USHORT Offset,
|
||||
PVOID Buffer,
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG_PTR Address;
|
||||
|
||||
/* Calculate the physical address */
|
||||
Address = (Segment << 4) + Offset;
|
||||
|
||||
/* Check if it's valid */
|
||||
if (!x86BiosIsInitialized || Address + Size > 0x100000)
|
||||
{
|
||||
/* Invalid */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Copy the memory to the buffer */
|
||||
RtlCopyMemory(Buffer, x86BiosMemoryMapping + Address, Size);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
x86BiosWriteMemory(
|
||||
USHORT Segment,
|
||||
USHORT Offset,
|
||||
PVOID Buffer,
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG_PTR Address;
|
||||
|
||||
/* Calculate the physical address */
|
||||
Address = (Segment << 4) + Offset;
|
||||
|
||||
/* Check if it's valid */
|
||||
if (!x86BiosIsInitialized || Address + Size > 0x100000)
|
||||
{
|
||||
/* Invalid */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Copy the memory from the buffer */
|
||||
RtlCopyMemory(x86BiosMemoryMapping + Address, Buffer, Size);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
x86BiosCall(
|
||||
ULONG InterruptNumber,
|
||||
X86_BIOS_REGISTERS *Registers)
|
||||
{
|
||||
X86_VM_STATE VmState;
|
||||
struct
|
||||
{
|
||||
USHORT Ip;
|
||||
USHORT SegCs;
|
||||
} *InterrupTable;
|
||||
|
||||
/* Zero the VmState */
|
||||
RtlZeroMemory(&VmState, sizeof(VmState));
|
||||
|
||||
/* Copy the registers */
|
||||
VmState.BiosRegisters = *Registers;
|
||||
|
||||
/* Set the physical memory buffer */
|
||||
VmState.MemBuffer = x86BiosMemoryMapping;
|
||||
|
||||
/* Set Eflags */
|
||||
VmState.Registers.Eflags.Long = 0; // FIXME
|
||||
|
||||
/* Setup stack */
|
||||
VmState.Registers.SegSs = 0; // FIXME
|
||||
VmState.Registers.Sp = 0x2000 - 2; // FIXME
|
||||
|
||||
/* Initialize IP from the interrupt vector table */
|
||||
InterrupTable = (PVOID)x86BiosMemoryMapping;
|
||||
VmState.Registers.SegCs = InterrupTable[InterruptNumber].SegCs;
|
||||
VmState.Registers.Eip = InterrupTable[InterruptNumber].Ip;
|
||||
|
||||
/* Make the function return on IRET */
|
||||
VmState.Flags.ReturnOnIret = 1;
|
||||
|
||||
/* Call the x86 emulator */
|
||||
x86Emulator(&VmState);
|
||||
|
||||
/* Copy registers back to caller */
|
||||
*Registers = VmState.BiosRegisters;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpBiosDisplayReset(VOID)
|
||||
{
|
||||
X86_BIOS_REGISTERS Registers;
|
||||
ULONG OldEflags;
|
||||
|
||||
/* Save flags and disable interrupts */
|
||||
OldEflags = __readeflags();
|
||||
_disable();
|
||||
|
||||
/* Set AH = 0 (Set video mode), AL = 0x12 (640x480x16 vga) */
|
||||
Registers.Eax = 0x12;
|
||||
|
||||
/* Call INT 0x10 */
|
||||
x86BiosCall(0x10, &Registers);
|
||||
|
||||
// FIXME: check result
|
||||
|
||||
/* Restore previous flags */
|
||||
__writeeflags(OldEflags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1 +1,27 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<group xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<module name="hal" type="kernelmodedll" entrypoint="HalInitSystem" installbase="system32" installname="hal.dll">
|
||||
<importlibrary base="hal" definition="../hal.pspec" />
|
||||
<bootstrap installbase="$(CDOUTPUT)" nameoncd="hal.dll" />
|
||||
<include base="hal">include</include>
|
||||
<include base="ntoskrnl">include</include>
|
||||
<!-- include base="x86emu">.</include -->
|
||||
<define name="_DISABLE_TIDENTS" />
|
||||
<define name="_NTHAL_" />
|
||||
<define name="_X86BIOS_" />
|
||||
<library>hal_generic</library>
|
||||
<library>hal_generic_up</library>
|
||||
<library>ntoskrnl</library>
|
||||
<!-- library>x86emu</library -->
|
||||
|
||||
<directory name="mp">
|
||||
<file>halinit_mp.c</file>
|
||||
<file>halmp.rc</file>
|
||||
<directory name="amd64">
|
||||
<!-- file>mps.S</file -->
|
||||
</directory>
|
||||
</directory>
|
||||
</module>
|
||||
</group>
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/amd64/generic/mps.S
|
||||
* PURPOSE: Intel MultiProcessor specification support
|
||||
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/amd64/asm.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#define BEFORE \
|
||||
cld; \
|
||||
push rax; \
|
||||
push rbx; \
|
||||
push rcx; \
|
||||
push rdx; \
|
||||
push rsi; \
|
||||
push rdi; \
|
||||
push fs; \
|
||||
push gs; \
|
||||
|
||||
#define AFTER \
|
||||
pop gs; \
|
||||
pop fs; \
|
||||
pop rdi; \
|
||||
pop rsi; \
|
||||
pop rdx; \
|
||||
pop rcx; \
|
||||
pop rbx; \
|
||||
pop rax; \
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
PUBLIC MpsIpiInterrupt
|
||||
MpsIpiInterrupt:
|
||||
/* Save registers */
|
||||
BEFORE
|
||||
|
||||
/* Call the C handler */
|
||||
call MpsIpiHandler
|
||||
|
||||
/* Return to the caller */
|
||||
AFTER
|
||||
iret
|
||||
#endif
|
||||
|
||||
PUBLIC MpsErrorInterrupt
|
||||
MpsErrorInterrupt:
|
||||
/* Save registers */
|
||||
BEFORE
|
||||
|
||||
/* Call the C handler */
|
||||
call MpsErrorHandler
|
||||
|
||||
/* Return to the caller */
|
||||
AFTER
|
||||
iret
|
||||
|
||||
|
||||
PUBLIC MpsSpuriousInterrupt
|
||||
MpsSpuriousInterrupt:
|
||||
/* Save registers */
|
||||
BEFORE
|
||||
|
||||
/* Call the C handler */
|
||||
call MpsSpuriousHandler
|
||||
|
||||
/* Return to the caller */
|
||||
AFTER
|
||||
iret
|
||||
|
||||
PUBLIC MpsTimerInterrupt
|
||||
MpsTimerInterrupt:
|
||||
/* Save registers */
|
||||
BEFORE
|
||||
|
||||
mov ebx, 0xef
|
||||
mov eax, 0xceafbeef
|
||||
push rax
|
||||
push rsp
|
||||
push rbx
|
||||
call MpsTimerHandler
|
||||
pop rax
|
||||
pop rax
|
||||
pop rax
|
||||
|
||||
/* Return to the caller */
|
||||
AFTER
|
||||
iret
|
||||
|
||||
|
||||
/* EOF */
|
||||
Reference in New Issue
Block a user