ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

x86bios.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS HAL
00003  * LICENSE:         GPL, See COPYING in the top level directory
00004  * FILE:            hal/halx86/generic/amd64/x86bios.c
00005  * PURPOSE:         
00006  * PROGRAMMERS:     Timo Kreuzer (timo.kreuzer@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <hal.h>
00012 //#define NDEBUG
00013 #include <debug.h>
00014 
00015 //#include "x86emu.h"
00016 
00017 /* This page serves as fallback for pages used by Mm */
00018 #define DEFAULT_PAGE 0x21
00019 
00020 /* GLOBALS *******************************************************************/
00021 
00022 BOOLEAN x86BiosIsInitialized;
00023 LONG x86BiosBufferIsAllocated = 0;
00024 PUCHAR x86BiosMemoryMapping;
00025 
00026 
00027 VOID
00028 NTAPI
00029 DbgDumpPage(PUCHAR MemBuffer, USHORT Segment)
00030 {
00031     ULONG x, y, Offset;
00032 
00033     for (y = 0; y < 0x100; y++)
00034     {
00035         for (x = 0; x < 0x10; x++)
00036         {
00037             Offset = Segment * 16 + y * 16 + x;
00038             DbgPrint("%02x ", MemBuffer[Offset]);
00039         }
00040         DbgPrint("\n");
00041     }
00042 }
00043 
00044 VOID
00045 NTAPI
00046 HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock)
00047 {
00048     PPFN_NUMBER PfnArray;
00049     PFN_NUMBER Pfn, Last;
00050     PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
00051     PLIST_ENTRY ListEntry;
00052     PMDL Mdl;
00053 
00054     /* Allocate an MDL for 1MB */
00055     Mdl = IoAllocateMdl(NULL, 0x100000, FALSE, FALSE, NULL);
00056     if (!Mdl)
00057     {
00058         ASSERT(FALSE);
00059     }
00060 
00061     /* Get pointer to the pfn array */
00062     PfnArray = MmGetMdlPfnArray(Mdl);
00063 
00064     /* Fill the array with low memory PFNs */
00065     for (Pfn = 0; Pfn < 0x100; Pfn++)
00066     {
00067         PfnArray[Pfn] = Pfn;
00068     }
00069 
00070     /* Loop the memory descriptors */
00071     for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
00072          ListEntry != &LoaderBlock->MemoryDescriptorListHead;
00073          ListEntry = ListEntry->Flink)
00074     {
00075         /* Get the memory descriptor */
00076         Descriptor = CONTAINING_RECORD(ListEntry,
00077                                        MEMORY_ALLOCATION_DESCRIPTOR,
00078                                        ListEntry);
00079 
00080         /* Check if the memory is in the low range */
00081         if (Descriptor->BasePage < 0x100)
00082         {
00083             /* Check if the memory type is firmware */
00084             if (Descriptor->MemoryType != LoaderFirmwarePermanent &&
00085                 Descriptor->MemoryType != LoaderSpecialMemory)
00086             {
00087                 /* It's something else, so don't use it! */
00088                 Last = min(Descriptor->BasePage + Descriptor->PageCount, 0x100);
00089                 for (Pfn = Descriptor->BasePage; Pfn < Last; Pfn++)
00090                 {
00091                     /* Set each page to the default page */
00092                     PfnArray[Pfn] = DEFAULT_PAGE;
00093                 }
00094             }
00095         }
00096     }
00097 
00098     Mdl->MdlFlags = MDL_PAGES_LOCKED;
00099 
00100     /* Map the MDL to system space */
00101     x86BiosMemoryMapping = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
00102     ASSERT(x86BiosMemoryMapping);
00103 
00104     DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8));
00105     //DbgDumpPage(x86BiosMemoryMapping, 0xc351);
00106 
00107     x86BiosIsInitialized = TRUE;
00108     
00109     HalpBiosDisplayReset();
00110 }
00111 
00112 NTSTATUS
00113 NTAPI
00114 x86BiosAllocateBuffer(
00115     ULONG *Size,
00116     USHORT *Segment,
00117     USHORT *Offset)
00118 {
00119     /* Check if the system is initialized and the buffer is large enough */
00120     if (!x86BiosIsInitialized || *Size > PAGE_SIZE)
00121     {
00122         /* Something was wrong, fail! */
00123         return STATUS_INSUFFICIENT_RESOURCES;
00124     }
00125 
00126     /* Check if the buffer is already allocated */
00127     if (InterlockedBitTestAndSet(&x86BiosBufferIsAllocated, 0))
00128     {
00129         /* Buffer was already allocated, fail */
00130         return STATUS_INSUFFICIENT_RESOURCES;
00131     }
00132 
00133     /* The buffer is sufficient, return hardcoded address and size */
00134     *Size = PAGE_SIZE;
00135     *Segment = 0x2000;
00136     *Offset = 0;
00137 
00138     return STATUS_SUCCESS;;
00139 }
00140 
00141 NTSTATUS
00142 NTAPI
00143 x86BiosFreeBuffer(
00144     USHORT Segment,
00145     USHORT Offset)
00146 {
00147     /* Check if the system is initialized and if the address matches */
00148     if (!x86BiosIsInitialized || Segment != 0x2000 || Offset != 0)
00149     {
00150         /* Something was wrong, fail */
00151         return STATUS_INVALID_PARAMETER;
00152     }
00153 
00154     /* Check if the buffer was allocated */
00155     if (!InterlockedBitTestAndReset(&x86BiosBufferIsAllocated, 0))
00156     {
00157         /* It was not, fail */
00158         return STATUS_INVALID_PARAMETER;
00159     }
00160 
00161     /* Buffer is freed, nothing more to do */
00162     return STATUS_SUCCESS;;
00163 }
00164 
00165 NTSTATUS
00166 NTAPI
00167 x86BiosReadMemory(
00168     USHORT Segment,
00169     USHORT Offset,
00170     PVOID Buffer,
00171     ULONG Size)
00172 {
00173     ULONG_PTR Address;
00174 
00175     /* Calculate the physical address */
00176     Address = (Segment << 4) + Offset;
00177 
00178     /* Check if it's valid */
00179     if (!x86BiosIsInitialized || Address + Size > 0x100000)
00180     {
00181         /* Invalid */
00182         return STATUS_INVALID_PARAMETER;
00183     }
00184 
00185     /* Copy the memory to the buffer */
00186     RtlCopyMemory(Buffer, x86BiosMemoryMapping + Address, Size);
00187 
00188     /* Return success */
00189     return STATUS_SUCCESS;
00190 }
00191 
00192 NTSTATUS
00193 NTAPI
00194 x86BiosWriteMemory(
00195     USHORT Segment,
00196     USHORT Offset,
00197     PVOID Buffer,
00198     ULONG Size)
00199 {
00200     ULONG_PTR Address;
00201 
00202     /* Calculate the physical address */
00203     Address = (Segment << 4) + Offset;
00204 
00205     /* Check if it's valid */
00206     if (!x86BiosIsInitialized || Address + Size > 0x100000)
00207     {
00208         /* Invalid */
00209         return STATUS_INVALID_PARAMETER;
00210     }
00211 
00212     /* Copy the memory from the buffer */
00213     RtlCopyMemory(x86BiosMemoryMapping + Address, Buffer, Size);
00214 
00215     /* Return success */
00216     return STATUS_SUCCESS;
00217 }
00218 
00219 #if 0
00220 BOOLEAN
00221 NTAPI
00222 x86BiosCall(
00223     ULONG InterruptNumber,
00224     X86_BIOS_REGISTERS *Registers)
00225 {
00226     X86_VM_STATE VmState;
00227     struct
00228     {
00229         USHORT Ip;
00230         USHORT SegCs;
00231     } *InterrupTable;
00232 
00233     /* Zero the VmState */
00234     RtlZeroMemory(&VmState, sizeof(VmState));
00235 
00236     /* Copy the registers */
00237     VmState.BiosRegisters = *Registers;
00238 
00239     /* Set the physical memory buffer */
00240     VmState.MemBuffer = x86BiosMemoryMapping;
00241 
00242     /* Set Eflags */
00243     VmState.Registers.Eflags.Long = 0; // FIXME
00244 
00245     /* Setup stack */
00246     VmState.Registers.SegSs = 0; // FIXME
00247     VmState.Registers.Sp = 0x2000 - 2; // FIXME
00248 
00249     /* Initialize IP from the interrupt vector table */
00250     InterrupTable = (PVOID)x86BiosMemoryMapping;
00251     VmState.Registers.SegCs = InterrupTable[InterruptNumber].SegCs;
00252     VmState.Registers.Eip = InterrupTable[InterruptNumber].Ip;
00253     
00254     /* Make the function return on IRET */
00255     VmState.Flags.ReturnOnIret = 1;
00256 
00257     /* Call the x86 emulator */
00258     x86Emulator(&VmState);
00259 
00260     /* Copy registers back to caller */
00261     *Registers = VmState.BiosRegisters;
00262 
00263     return TRUE;
00264 }
00265 #endif
00266 
00267 BOOLEAN
00268 NTAPI
00269 HalpBiosDisplayReset(VOID)
00270 {
00271 #if 0
00272     X86_BIOS_REGISTERS Registers;
00273     ULONG OldEflags;
00274 
00275     /* Save flags and disable interrupts */
00276     OldEflags = __readeflags();
00277     _disable();
00278 
00279     /* Set AH = 0 (Set video mode), AL = 0x12 (640x480x16 vga) */
00280     Registers.Eax = 0x12;
00281 
00282     /* Call INT 0x10 */
00283     x86BiosCall(0x10, &Registers);
00284 
00285     // FIXME: check result
00286 
00287     /* Restore previous flags */
00288     __writeeflags(OldEflags);
00289 #endif
00290     return TRUE;
00291 }
00292 

Generated on Sun May 27 2012 04:28:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.