[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 9 May 2015 23:48:09 +0000 (23:48 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 9 May 2015 23:48:09 +0000 (23:48 +0000)
Implement BIOS INT 15h functions AX = E820 (Get Memory Map) and AX = E801
(Get Memory Size for >64M Configurations).

svn path=/trunk/; revision=67609

reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h
reactos/subsystems/mvdm/ntvdm/memory.c
reactos/subsystems/mvdm/ntvdm/memory.h

index 29efe32..b1ca65a 100644 (file)
@@ -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",
index 4f1523f..24efa8d 100644 (file)
 
 /* 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
index e6c8723..de9b18e 100644 (file)
@@ -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
index ac41697..e41a9d1 100644 (file)
@@ -67,6 +67,14 @@ MemRemoveFastMemoryHook
     ULONG Size
 );
 
+BOOLEAN
+MemQueryMemoryZone
+(
+    ULONG StartAddress,
+    PULONG Length,
+    PBOOLEAN Hooked
+);
+
 #endif // _MEMORY_H_
 
 /* EOF */