mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +00:00
[FREELDR]
Patch by Brian Palmer: Properly handle a memory hole below 16MB, which some machines have. svn path=/trunk/; revision=53796
This commit is contained in:
parent
84727b099d
commit
994898f151
1 changed files with 100 additions and 80 deletions
|
@ -27,95 +27,100 @@
|
||||||
|
|
||||||
DBG_DEFAULT_CHANNEL(MEMORY);
|
DBG_DEFAULT_CHANNEL(MEMORY);
|
||||||
|
|
||||||
static ULONG
|
static
|
||||||
PcMemGetExtendedMemorySize(VOID)
|
BOOLEAN
|
||||||
|
GetExtendedMemoryConfiguration(ULONG* pMemoryAtOneMB /* in KB */, ULONG* pMemoryAtSixteenMB /* in 64KB */)
|
||||||
{
|
{
|
||||||
REGS RegsIn;
|
REGS RegsIn;
|
||||||
REGS RegsOut;
|
REGS RegsOut;
|
||||||
ULONG MemorySize;
|
|
||||||
|
|
||||||
TRACE("GetExtendedMemorySize()\n");
|
TRACE("GetExtendedMemoryConfiguration()\n");
|
||||||
|
|
||||||
/* Int 15h AX=E801h
|
*pMemoryAtOneMB = 0;
|
||||||
* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
|
*pMemoryAtSixteenMB = 0;
|
||||||
*
|
|
||||||
* AX = E801h
|
|
||||||
* Return:
|
|
||||||
* CF clear if successful
|
|
||||||
* AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
|
|
||||||
* BX = extended memory above 16M, in 64K blocks
|
|
||||||
* CX = configured memory 1M to 16M, in K
|
|
||||||
* DX = configured memory above 16M, in 64K blocks
|
|
||||||
* CF set on error
|
|
||||||
*/
|
|
||||||
RegsIn.w.ax = 0xE801;
|
|
||||||
Int386(0x15, &RegsIn, &RegsOut);
|
|
||||||
|
|
||||||
TRACE("Int15h AX=E801h\n");
|
// Int 15h AX=E801h
|
||||||
TRACE("AX = 0x%x\n", RegsOut.w.ax);
|
// Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
|
||||||
TRACE("BX = 0x%x\n", RegsOut.w.bx);
|
//
|
||||||
TRACE("CX = 0x%x\n", RegsOut.w.cx);
|
// AX = E801h
|
||||||
TRACE("DX = 0x%x\n", RegsOut.w.dx);
|
// Return:
|
||||||
TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
|
// CF clear if successful
|
||||||
|
// AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
|
||||||
|
// BX = extended memory above 16M, in 64K blocks
|
||||||
|
// CX = configured memory 1M to 16M, in K
|
||||||
|
// DX = configured memory above 16M, in 64K blocks
|
||||||
|
// CF set on error
|
||||||
|
RegsIn.w.ax = 0xE801;
|
||||||
|
Int386(0x15, &RegsIn, &RegsOut);
|
||||||
|
|
||||||
if (INT386_SUCCESS(RegsOut))
|
TRACE("Int15h AX=E801h\n");
|
||||||
|
TRACE("AX = 0x%x\n", RegsOut.w.ax);
|
||||||
|
TRACE("BX = 0x%x\n", RegsOut.w.bx);
|
||||||
|
TRACE("CX = 0x%x\n", RegsOut.w.cx);
|
||||||
|
TRACE("DX = 0x%x\n", RegsOut.w.dx);
|
||||||
|
TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
|
if (INT386_SUCCESS(RegsOut))
|
||||||
{
|
{
|
||||||
/* If AX=BX=0000h the use CX and DX */
|
// If AX=BX=0000h the use CX and DX
|
||||||
if (RegsOut.w.ax == 0)
|
if (RegsOut.w.ax == 0)
|
||||||
{
|
{
|
||||||
/* Return extended memory size in K */
|
// Return extended memory size in K
|
||||||
MemorySize = RegsOut.w.dx * 64;
|
*pMemoryAtSixteenMB = RegsOut.w.dx;
|
||||||
MemorySize += RegsOut.w.cx;
|
*pMemoryAtOneMB = RegsOut.w.cx;
|
||||||
return MemorySize;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Return extended memory size in K */
|
// Return extended memory size in K
|
||||||
MemorySize = RegsOut.w.bx * 64;
|
*pMemoryAtSixteenMB = RegsOut.w.bx;
|
||||||
MemorySize += RegsOut.w.ax;
|
*pMemoryAtOneMB = RegsOut.w.ax;
|
||||||
return MemorySize;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here then Int15 Func E801h didn't work */
|
// If we get here then Int15 Func E801h didn't work
|
||||||
/* So try Int15 Func 88h */
|
// So try Int15 Func 88h
|
||||||
|
// Int 15h AH=88h
|
||||||
|
// SYSTEM - GET EXTENDED MEMORY SIZE (286+)
|
||||||
|
//
|
||||||
|
// AH = 88h
|
||||||
|
// Return:
|
||||||
|
// CF clear if successful
|
||||||
|
// AX = number of contiguous KB starting at absolute address 100000h
|
||||||
|
// CF set on error
|
||||||
|
// AH = status
|
||||||
|
// 80h invalid command (PC,PCjr)
|
||||||
|
// 86h unsupported function (XT,PS30)
|
||||||
|
RegsIn.b.ah = 0x88;
|
||||||
|
Int386(0x15, &RegsIn, &RegsOut);
|
||||||
|
|
||||||
/* Int 15h AH=88h
|
TRACE("Int15h AH=88h\n");
|
||||||
* SYSTEM - GET EXTENDED MEMORY SIZE (286+)
|
TRACE("AX = 0x%x\n", RegsOut.w.ax);
|
||||||
*
|
TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
|
||||||
* AH = 88h
|
|
||||||
* Return:
|
|
||||||
* CF clear if successful
|
|
||||||
* AX = number of contiguous KB starting at absolute address 100000h
|
|
||||||
* CF set on error
|
|
||||||
* AH = status
|
|
||||||
* 80h invalid command (PC,PCjr)
|
|
||||||
* 86h unsupported function (XT,PS30)
|
|
||||||
*/
|
|
||||||
RegsIn.b.ah = 0x88;
|
|
||||||
Int386(0x15, &RegsIn, &RegsOut);
|
|
||||||
|
|
||||||
TRACE("Int15h AH=88h\n");
|
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
|
||||||
TRACE("AX = 0x%x\n", RegsOut.w.ax);
|
|
||||||
TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
|
|
||||||
|
|
||||||
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
|
|
||||||
{
|
{
|
||||||
MemorySize = RegsOut.w.ax;
|
*pMemoryAtOneMB = RegsOut.w.ax;
|
||||||
return MemorySize;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here then Int15 Func 88h didn't work */
|
// If we get here then Int15 Func 88h didn't work
|
||||||
/* So try reading the CMOS */
|
// So try reading the CMOS
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
|
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
|
||||||
MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
|
*pMemoryAtOneMB = READ_PORT_UCHAR((PUCHAR)0x71);
|
||||||
MemorySize = (MemorySize & 0xFFFF);
|
*pMemoryAtOneMB = (*pMemoryAtOneMB & 0xFFFF);
|
||||||
MemorySize = (MemorySize << 8);
|
*pMemoryAtOneMB = (*pMemoryAtOneMB << 8);
|
||||||
|
|
||||||
TRACE("Int15h Failed\n");
|
TRACE("Int15h Failed\n");
|
||||||
TRACE("CMOS reports: 0x%x\n", MemorySize);
|
TRACE("CMOS reports: 0x%x\n", *pMemoryAtOneMB);
|
||||||
|
|
||||||
return MemorySize;
|
if (*pMemoryAtOneMB != 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
|
@ -228,21 +233,36 @@ ULONG
|
||||||
PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
|
PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
|
||||||
{
|
{
|
||||||
ULONG EntryCount;
|
ULONG EntryCount;
|
||||||
|
ULONG ExtendedMemorySizeAtOneMB;
|
||||||
|
ULONG ExtendedMemorySizeAtSixteenMB;
|
||||||
|
|
||||||
EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
|
EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
|
||||||
|
|
||||||
/* If the BIOS didn't provide a memory map, synthesize one */
|
/* If the BIOS didn't provide a memory map, synthesize one */
|
||||||
if (0 == EntryCount && 2 <= MaxMemoryMapSize)
|
if (0 == EntryCount && 3 <= MaxMemoryMapSize)
|
||||||
{
|
{
|
||||||
/* Conventional memory */
|
GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB);
|
||||||
BiosMemoryMap[0].BaseAddress = 0;
|
|
||||||
BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024;
|
/* Conventional memory */
|
||||||
BiosMemoryMap[0].Type = BiosMemoryUsable;
|
BiosMemoryMap[EntryCount].BaseAddress = 0;
|
||||||
/* Extended memory */
|
BiosMemoryMap[EntryCount].Length = PcMemGetConventionalMemorySize() * 1024;
|
||||||
BiosMemoryMap[1].BaseAddress = 1024 * 1024;
|
BiosMemoryMap[EntryCount].Type = BiosMemoryUsable;
|
||||||
BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024;
|
EntryCount++;
|
||||||
BiosMemoryMap[1].Type = BiosMemoryUsable;
|
|
||||||
EntryCount = 2;
|
/* Extended memory at 1MB */
|
||||||
|
BiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024;
|
||||||
|
BiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024;
|
||||||
|
BiosMemoryMap[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;
|
||||||
|
EntryCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EntryCount;
|
return EntryCount;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue