From 18f771e535394771192085d9bd8136f67d3682f7 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sat, 9 May 2015 23:48:09 +0000 Subject: [PATCH] [NTVDM] Implement BIOS INT 15h functions AX = E820 (Get Memory Map) and AX = E801 (Get Memory Size for >64M Configurations). svn path=/trunk/; revision=67609 --- .../mvdm/ntvdm/bios/bios32/bios32.c | 63 +++++++++++++++++++ .../mvdm/ntvdm/bios/bios32/bios32.h | 15 +++++ reactos/subsystems/mvdm/ntvdm/memory.c | 16 +++++ reactos/subsystems/mvdm/ntvdm/memory.h | 8 +++ 4 files changed, 102 insertions(+) diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c index 29efe3267b0..b1ca65a9c83 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c @@ -27,6 +27,7 @@ #include "vidbios32.h" #include "moubios32.h" +#include "memory.h" #include "io.h" #include "hardware/cmos.h" #include "hardware/pic.h" @@ -291,6 +292,68 @@ static VOID WINAPI BiosMiscService(LPWORD Stack) break; } + /* Get System Memory Map */ + case 0xE8: + { + if (getAL() == 0x01) + { + /* The amount of memory between 1M and 16M, in kilobytes */ + ULONG Above1M = (min(MAX_ADDRESS, 0x01000000) - 0x00100000) >> 10; + + /* The amount of memory above 16M, in 64K blocks */ + ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? (MAX_ADDRESS - 0x01000000) >> 16: 0; + + setCF(0); + setAX(Above1M); + setBX(Above16M); + setCX(Above1M); + setDX(Above16M); + } + else if (getAL() == 0x20 && getEDX() == 'PAMS') + { + ULONG Offset = getEBX(); + ULONG Length; + ULONG BytesWritten = 0; + BOOLEAN Hooked; + PBIOS_MEMORY_MAP Map = (PBIOS_MEMORY_MAP)SEG_OFF_TO_PTR(getES(), getDI()); + + /* Assume the buffer won't be large enough */ + setCF(0); + + while (BytesWritten < getECX() && (ULONG_PTR)Map < (MAX_ADDRESS - sizeof(BIOS_MEMORY_MAP))) + { + /* Let's ask our memory controller */ + if (!MemQueryMemoryZone(Offset, &Length, &Hooked)) + { + /* No more memory blocks */ + setCF(1); + break; + } + + Map->BaseAddress = (ULONGLONG)Offset; + Map->Length = (ULONGLONG)Length; + Map->Type = Hooked ? BIOS_MEMORY_RESERVED : BIOS_MEMORY_AVAILABLE; + + /* Go to the next record */ + Map++; + Offset += Length; + BytesWritten += sizeof(BIOS_MEMORY_MAP); + } + + setEAX('PAMS'); + setEBX(Offset); + setECX(BytesWritten); + } + else + { + DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X, EDX = %08X\n", + getAL(), + getEDX()); + } + + break; + } + default: { DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n", diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h index 4f1523fa1d7..24efa8d1ce4 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h @@ -15,6 +15,21 @@ /* DEFINES ********************************************************************/ +enum +{ + BIOS_MEMORY_AVAILABLE = 1, + BIOS_MEMORY_RESERVED = 2, + BIOS_MEMORY_ACPI_RECLAIMABLE = 3, + BIOS_MEMORY_ACPI_NVS = 4 +}; + +typedef struct +{ + ULONGLONG BaseAddress; + ULONGLONG Length; + ULONG Type; +} BIOS_MEMORY_MAP, *PBIOS_MEMORY_MAP; + // #define BIOS_EQUIPMENT_INTERRUPT 0x11 // #define BIOS_MEMORY_SIZE 0x12 // #define BIOS_MISC_INTERRUPT 0x15 diff --git a/reactos/subsystems/mvdm/ntvdm/memory.c b/reactos/subsystems/mvdm/ntvdm/memory.c index e6c8723c96b..de9b18e771c 100644 --- a/reactos/subsystems/mvdm/ntvdm/memory.c +++ b/reactos/subsystems/mvdm/ntvdm/memory.c @@ -283,7 +283,23 @@ MemRemoveFastMemoryHook(PVOID Address, ULONG Size) return TRUE; } +BOOLEAN +MemQueryMemoryZone(ULONG StartAddress, PULONG Length, PBOOLEAN Hooked) +{ + ULONG Page = StartAddress >> 12; + if (Page >= TOTAL_PAGES) return FALSE; + *Length = 0; + *Hooked = PageTable[Page] != NULL; + + while (Page < TOTAL_PAGES && (PageTable[Page] != NULL) == *Hooked) + { + *Length += PAGE_SIZE; + Page++; + } + + return TRUE; +} PBYTE WINAPI diff --git a/reactos/subsystems/mvdm/ntvdm/memory.h b/reactos/subsystems/mvdm/ntvdm/memory.h index ac4169725bd..e41a9d16b60 100644 --- a/reactos/subsystems/mvdm/ntvdm/memory.h +++ b/reactos/subsystems/mvdm/ntvdm/memory.h @@ -67,6 +67,14 @@ MemRemoveFastMemoryHook ULONG Size ); +BOOLEAN +MemQueryMemoryZone +( + ULONG StartAddress, + PULONG Length, + PBOOLEAN Hooked +); + #endif // _MEMORY_H_ /* EOF */