From b3562752620a82f135456409864d2f234974c9f1 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 22 Sep 2011 16:38:54 +0000 Subject: [PATCH] [FREELDR] - Fix a bug, where the bios memory map could have a bogus entry: according to R.B.'s Interrupt list, in some bioses the function for enumerating the memory can return ebx != 0 for the last descriptor, and fail in the following call returning CF = 1. In that case we were previously counting that last descriptor as well, but its content wouldn't describe a valid memory region. - Use a static buffer for the bios memory map, stored in the achitecture specific file and return a pointer to that variable from PcMemGetMemoryMap. Reuse the static map from DetectAcpiBios instead of enumerating again. On arm, we don't even need a buffer, we return the pointer from the arm block. svn path=/trunk/; revision=53803 --- .../boot/freeldr/freeldr/arch/arm/macharm.c | 11 ++-- .../boot/freeldr/freeldr/arch/i386/hwacpi.c | 16 ++--- .../boot/freeldr/freeldr/arch/i386/pcmem.c | 63 ++++++++++--------- .../boot/freeldr/freeldr/arch/i386/xboxmem.c | 19 ++---- .../freeldr/include/arch/i386/machxbox.h | 2 +- .../freeldr/freeldr/include/arch/pc/machpc.h | 5 +- .../boot/freeldr/freeldr/include/machine.h | 2 +- reactos/boot/freeldr/freeldr/mm/meminit.c | 8 +-- 8 files changed, 57 insertions(+), 69 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c index 5688406e2e8..53591232bc4 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c @@ -143,15 +143,12 @@ ArmHwDetect(VOID) return RootNode; } -ULONG -ArmMemGetMemoryMap(OUT PBIOS_MEMORY_MAP BiosMemoryMap, - IN ULONG MaxMemoryMapSize) +PBIOS_MEMORY_MAP +ArmMemGetMemoryMap(OUT PULONG MaxMemoryMapSize) { /* Return whatever the board returned to us (CS0 Base + Size and FLASH0) */ - memcpy(BiosMemoryMap, - ArmBoardBlock->MemoryMap, - ArmBoardBlock->MemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP)); - return ArmBoardBlock->MemoryMapEntryCount; + *MaxMemoryMapSize = ArmBoardBlock->MemoryMapEntryCount; + return ArmBoardBlock->MemoryMap; } VOID diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c b/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c index e111958d3bd..96043d4abce 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c @@ -58,8 +58,7 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; PRSDP_DESCRIPTOR Rsdp; PACPI_BIOS_DATA AcpiBiosData; - BIOS_MEMORY_MAP BiosMemoryMap[32]; - ULONG BiosMemoryMapEntryCount, TableSize; + ULONG TableSize; Rsdp = FindAcpiBios(); @@ -68,13 +67,8 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) /* Set up the flag in the loader block */ AcpiPresent = TRUE; - /* Get BIOS memory map */ - RtlZeroMemory(BiosMemoryMap, sizeof(BiosMemoryMap)); - BiosMemoryMapEntryCount = PcMemGetMemoryMap(BiosMemoryMap, - sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP)); - /* Calculate the table size */ - TableSize = BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP) + + TableSize = PcBiosMapCount * sizeof(BIOS_MEMORY_MAP) + sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP); /* Set 'Configuration Data' value */ @@ -100,9 +94,9 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) /* Fill the table */ AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1]; AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address; - AcpiBiosData->Count = BiosMemoryMapEntryCount; - memcpy(AcpiBiosData->MemoryMap, BiosMemoryMap, - BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP)); + AcpiBiosData->Count = PcBiosMapCount; + memcpy(AcpiBiosData->MemoryMap, PcBiosMemoryMap, + PcBiosMapCount * sizeof(BIOS_MEMORY_MAP)); TRACE("RSDT %p, data size %x\n", Rsdp->rsdt_physical_address, TableSize); diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c index 0b6ffc32583..568c54a11e5 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -27,6 +27,11 @@ DBG_DEFAULT_CHANNEL(MEMORY); +#define MAX_BIOS_DESCRIPTORS 32 + +BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS]; +ULONG PcBiosMapCount; + static BOOLEAN GetExtendedMemoryConfiguration(ULONG* pMemoryAtOneMB /* in KB */, ULONG* pMemoryAtSixteenMB /* in 64KB */) @@ -174,14 +179,17 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) * CF set on error * AH = error code (86h) */ - Regs.x.eax = 0x0000E820; - Regs.x.edx = 0x534D4150; /* ('SMAP') */ Regs.x.ebx = 0x00000000; - Regs.x.ecx = sizeof(BIOS_MEMORY_MAP); - Regs.w.es = BIOSCALLBUFSEGMENT; - Regs.w.di = BIOSCALLBUFOFFSET; + for (MapCount = 0; MapCount < MaxMemoryMapSize; MapCount++) { + /* Setup the registers for the BIOS call */ + Regs.x.eax = 0x0000E820; + Regs.x.edx = 0x534D4150; /* ('SMAP') */ + /* Regs.x.ebx = 0x00000001; Continuation value already set */ + Regs.x.ecx = sizeof(BIOS_MEMORY_MAP); + Regs.w.es = BIOSCALLBUFSEGMENT; + Regs.w.di = BIOSCALLBUFOFFSET; Int386(0x15, &Regs, &Regs); TRACE("Memory Map Entry %d\n", MapCount); @@ -192,8 +200,8 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) TRACE("CF set = %s\n", (Regs.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE"); /* If the BIOS didn't return 'SMAP' in EAX then - * it doesn't support this call */ - if (Regs.x.eax != 0x534D4150) + * it doesn't support this call. If CF is set, we're done */ + if (Regs.x.eax != 0x534D4150 || !INT386_SUCCESS(Regs)) { break; } @@ -210,62 +218,57 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) /* If the continuation value is zero or the * carry flag is set then this was * the last entry so we're done */ - if (Regs.x.ebx == 0x00000000 || !INT386_SUCCESS(Regs)) + if (Regs.x.ebx == 0x00000000) { - MapCount++; TRACE("End Of System Memory Map!\n\n"); break; } - /* Setup the registers for the next call */ - Regs.x.eax = 0x0000E820; - Regs.x.edx = 0x534D4150; /* ('SMAP') */ - /* Regs.x.ebx = 0x00000001; Continuation value already set by the BIOS */ - Regs.x.ecx = sizeof(BIOS_MEMORY_MAP); - Regs.w.es = BIOSCALLBUFSEGMENT; - Regs.w.di = BIOSCALLBUFOFFSET; } return MapCount; } -ULONG -PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) +PBIOS_MEMORY_MAP +PcMemGetMemoryMap(ULONG *MemoryMapSize) { ULONG EntryCount; ULONG ExtendedMemorySizeAtOneMB; ULONG ExtendedMemorySizeAtSixteenMB; - EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize); + EntryCount = PcMemGetBiosMemoryMap(PcBiosMemoryMap, MAX_BIOS_DESCRIPTORS); + PcBiosMapCount = EntryCount; /* If the BIOS didn't provide a memory map, synthesize one */ - if (0 == EntryCount && 3 <= MaxMemoryMapSize) + if (0 == EntryCount) { GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB); /* Conventional memory */ - BiosMemoryMap[EntryCount].BaseAddress = 0; - BiosMemoryMap[EntryCount].Length = PcMemGetConventionalMemorySize() * 1024; - BiosMemoryMap[EntryCount].Type = BiosMemoryUsable; + PcBiosMemoryMap[EntryCount].BaseAddress = 0; + PcBiosMemoryMap[EntryCount].Length = PcMemGetConventionalMemorySize() * 1024; + PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; EntryCount++; /* Extended memory at 1MB */ - BiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024; - BiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024; - BiosMemoryMap[EntryCount].Type = BiosMemoryUsable; + PcBiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024; + PcBiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024; + PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; EntryCount++; if (ExtendedMemorySizeAtSixteenMB != 0) { /* Extended memory at 16MB */ - BiosMemoryMap[EntryCount].BaseAddress = 0x1000000; - BiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtSixteenMB * 64 * 1024; - BiosMemoryMap[EntryCount].Type = BiosMemoryUsable; + PcBiosMemoryMap[EntryCount].BaseAddress = 0x1000000; + PcBiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtSixteenMB * 64 * 1024; + PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; EntryCount++; } } - return EntryCount; + *MemoryMapSize = EntryCount; + + return PcBiosMemoryMap; } /* EOF */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c index 754f357cc34..f2e5e4a71e9 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c @@ -75,31 +75,24 @@ XboxMemInit(VOID) AvailableMemoryMb = InstalledMemoryMb; } -ULONG -XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) -{ - ULONG EntryCount = 0; +BIOS_MEMORY_MAP BiosMemoryMap[2]; +PBIOS_MEMORY_MAP +XboxMemGetMemoryMap(ULONG *MemoryMapSize) +{ /* Synthesize memory map */ - if (1 <= MaxMemoryMapSize) - { /* Available RAM block */ BiosMemoryMap[0].BaseAddress = 0; BiosMemoryMap[0].Length = AvailableMemoryMb * 1024 * 1024; BiosMemoryMap[0].Type = BiosMemoryUsable; - EntryCount = 1; - } - if (2 <= MaxMemoryMapSize) - { /* Video memory */ BiosMemoryMap[1].BaseAddress = AvailableMemoryMb * 1024 * 1024; BiosMemoryMap[1].Length = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024; BiosMemoryMap[1].Type = BiosMemoryReserved; - EntryCount = 2; - } - return EntryCount; + *MemoryMapSize = 2; + return BiosMemoryMap; } PVOID diff --git a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h index 241320ac189..b7ec5079573 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h +++ b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h @@ -49,7 +49,7 @@ VOID XboxPrepareForReactOS(IN BOOLEAN Setup); VOID XboxMemInit(VOID); PVOID XboxMemReserveMemory(ULONG MbToReserve); -ULONG XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize); +PBIOS_MEMORY_MAP XboxMemGetMemoryMap(ULONG *MemoryMapSize); BOOLEAN XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); BOOLEAN XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h index 43ca48a2b12..0a8b4ddeba7 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h @@ -46,7 +46,7 @@ VOID PcVideoSync(VOID); VOID PcVideoPrepareForReactOS(IN BOOLEAN Setup); VOID PcPrepareForReactOS(IN BOOLEAN Setup); -ULONG PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize); +PBIOS_MEMORY_MAP PcMemGetMemoryMap(ULONG *MemoryMapSize); BOOLEAN PcDiskGetBootPath(char *BootPath, unsigned Size); BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); @@ -58,4 +58,7 @@ TIMEINFO* PcGetTime(VOID); PCONFIGURATION_COMPONENT_DATA PcHwDetect(VOID); +extern BIOS_MEMORY_MAP PcBiosMemoryMap[]; +extern ULONG PcBiosMapCount; + /* EOF */ diff --git a/reactos/boot/freeldr/freeldr/include/machine.h b/reactos/boot/freeldr/freeldr/include/machine.h index 1e77b786e97..7235eb1d06f 100644 --- a/reactos/boot/freeldr/freeldr/include/machine.h +++ b/reactos/boot/freeldr/freeldr/include/machine.h @@ -59,7 +59,7 @@ typedef struct tagMACHVTBL VOID (*PrepareForReactOS)(IN BOOLEAN Setup); MEMORY_DESCRIPTOR* (*GetMemoryDescriptor)(MEMORY_DESCRIPTOR* Current); - ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize); + PBIOS_MEMORY_MAP (*GetMemoryMap)(PULONG MemoryMapSize); BOOLEAN (*DiskGetBootPath)(char *BootPath, unsigned Size); BOOLEAN (*DiskReadLogicalSectors)(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); diff --git a/reactos/boot/freeldr/freeldr/mm/meminit.c b/reactos/boot/freeldr/freeldr/mm/meminit.c index 98a787a7c52..bb7efaed488 100644 --- a/reactos/boot/freeldr/freeldr/mm/meminit.c +++ b/reactos/boot/freeldr/freeldr/mm/meminit.c @@ -124,7 +124,7 @@ const MEMORY_DESCRIPTOR* ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current) { MEMORY_DESCRIPTOR_INT* CurrentDescriptor; - BIOS_MEMORY_MAP BiosMemoryMap[32]; + PBIOS_MEMORY_MAP BiosMemoryMap; static ULONG BiosMemoryMapEntryCount; static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32]; static BOOLEAN MemoryMapInitialized = FALSE; @@ -138,10 +138,7 @@ ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current) // // Get the machine generated memory map // - RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32); - BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap, - sizeof(BiosMemoryMap) / - sizeof(BIOS_MEMORY_MAP)); + BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount); // // Fix entries that are not page aligned @@ -545,6 +542,7 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page { PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable; ULONG Index; + TRACE("MmMarkPagesInLookupTable()\n"); StartPage -= MmLowestPhysicalPage; for (Index=StartPage; Index<(StartPage+PageCount); Index++)