[ros-diffs] [tkreuzer] 44934: [HAL] Implement HalInitializeBios, x86BiosAllocateBuffer, x86BiosFreeBuffer, x86BiosReadMemory and x86BiosWriteMemory Halfplement x86BiosCall (We don't have the necessary emulator yet)

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Mon Jan 4 23:12:19 CET 2010


Author: tkreuzer
Date: Mon Jan  4 23:12:18 2010
New Revision: 44934

URL: http://svn.reactos.org/svn/reactos?rev=44934&view=rev
Log:
[HAL]
Implement HalInitializeBios, x86BiosAllocateBuffer, x86BiosFreeBuffer, x86BiosReadMemory and x86BiosWriteMemory
Halfplement x86BiosCall (We don't have the necessary emulator yet)

Modified:
    branches/ros-amd64-bringup/reactos/hal/halx86/generic/x86bios.c

Modified: branches/ros-amd64-bringup/reactos/hal/halx86/generic/x86bios.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/hal/halx86/generic/x86bios.c?rev=44934&r1=44933&r2=44934&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/hal/halx86/generic/x86bios.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/hal/halx86/generic/x86bios.c [iso-8859-1] Mon Jan  4 23:12:18 2010
@@ -3,7 +3,7 @@
  * LICENSE:         See COPYING in the top level directory
  * FILE:            hal/halamd64/generic/x86bios.c
  * PURPOSE:         
- * PROGRAMMERS:     
+ * PROGRAMMERS:     Timo Kreuzer (timo.kreuzer at reactos.org)
  */
 
 /* INCLUDES ******************************************************************/
@@ -11,6 +11,78 @@
 #include <hal.h>
 //#define NDEBUG
 #include <debug.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
+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 != LoaderFirmwarePermanent)
+            {
+                /* 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;
+                }
+            }
+        }
+    }
+
+    /* Map the MDL to system space */
+    x86BiosMemoryMapping = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
+    ASSERT(x86BiosMemoryMapping);
+
+    DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8));
+
+    x86BiosIsInitialized = TRUE;
+}
 
 NTSTATUS
 NTAPI
@@ -19,19 +91,26 @@
     USHORT *Segment,
     USHORT *Offset)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;;
-
-}
-
-BOOLEAN
-NTAPI
-x86BiosCall (
-    ULONG InterruptNumber,
-    X86_BIOS_REGISTERS *Registers)
-{
-    UNIMPLEMENTED;
-    return FALSE;
+    /* 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
@@ -40,19 +119,49 @@
     USHORT Segment,
     USHORT Offset)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;;
+    /* 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)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;;
+    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
@@ -63,7 +172,146 @@
     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;
+}
+
+typedef struct
+{
+    union
+    {
+        ULONG Eax;
+        USHORT Ax;
+        struct
+        {
+            UCHAR Al;
+            UCHAR Ah;
+        };
+    };
+    union
+    {
+        ULONG Ecx;
+        USHORT Cx;
+        struct
+        {
+            UCHAR Cl;
+            UCHAR Ch;
+        };
+    };
+    union
+    {
+        ULONG Edx;
+        USHORT Dx;
+        struct
+        {
+            UCHAR Dl;
+            UCHAR Dh;
+        };
+    };
+    union
+    {
+        ULONG Ebx;
+        USHORT Bx;
+        struct
+        {
+            UCHAR Bl;
+            UCHAR Bh;
+        };
+    };
+    ULONG Ebp;
+    ULONG Esi;
+    ULONG Edi;
+    USHORT SegDs;
+    USHORT SegEs;
+
+    /* Extended */
+    union
+    {
+        ULONG Eip;
+        USHORT Ip;
+    };
+
+    union
+    {
+        ULONG Esp;
+        USHORT Sp;
+    };
+
+} X86_REGISTERS, *PX86_REGISTERS;
+
+enum
+{
+    X86_VMFLAGS_RETURN_ON_IRET = 1,
+};
+
+typedef struct
+{
+    union
+    {
+        X86_BIOS_REGISTERS BiosRegisters;
+        X86_REGISTERS Registers;
+    };
+    
+    struct
+    {
+        ULONG ReturnOnIret:1;
+    } Flags;
+    
+    PVOID MemBuffer;
+} X86_VM_STATE, *PX86_VM_STATE;
+
+BOOLEAN
+NTAPI
+x86BiosCall (
+    ULONG InterruptNumber,
+    X86_BIOS_REGISTERS *Registers)
+{
+    X86_VM_STATE VmState;
+
+    /* Zero the VmState */
+    RtlZeroMemory(&VmState, sizeof(VmState));
+
+    /* Copy the registers */
+    VmState.BiosRegisters = *Registers;
+
+    /* Set the physical memory buffer */
+    VmState.MemBuffer = x86BiosMemoryMapping;
+
+    /* Initialize IP from the interrupt vector table */
+    VmState.Registers.Ip = ((PUSHORT)x86BiosMemoryMapping)[InterruptNumber];
+
+    /* 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)
+{
     UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;;
-}
-
+    return TRUE;
+}
+




More information about the Ros-diffs mailing list