mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
ARM Port Memory Management Checkpoint:
- Implemented and defined the MMU-OS architecture for the ARM port. The details are too long for a commit message, but we have decided to replicate the x86 NT memory manager layout. We've defined a PTE_BASE at 0xC0000000 just like on x86, and we use a PDE_BASE at 0xC1000000. Unlike the x86, we can't use PDE-PTE self-mapping because ARM has different formats (and sizes!) for PDE vs PTEs! We emulate the behavior however (which adds a small performance hit) and the Mm porting is thus at least 10 times easier. - Moved serial port to 0xE0000000 for now. - We now parse the board memory map from u-boot. - Added memory allocation code to FreeLDR -- we now build a full ARC memory map for the kernel. - FreeLDR allocates page tables and sets up the initial support for our memory layout (see comments for some lengthier explenations) - Allocations made by FreeLDR for loading ReactOS are now made from a "shared heap" page that's also marked in the memory map. - Registry and NLS data are now being put into the loader block. - We now create a loader entry for the kernel (but not anything else -- we'll have to parse the list properly later). - Defined correct _HARDWARE_PTE_ARM and _MMPTE_HARDWARE for ARM. - ARM_COARSE_PAGE_TABLE is now 4KB instead of 1KB, going against the architecture! We do this for proper OS support of the PTE_BASE. - Fixed build due to KiSystemStartulReal change. - Fixed a bug on the x86 build when creating memory allocation descriptors. Memory corruption could occur in certain scenarios. - Implemented significant portions of the ARM memory manager code in the kernel: - MmGetPageDirectory. - MmDeletePageTable (for the kernel address space only). - MmIsPagePresent (for the kernel address space only). - MmCreateVirtualMappingForKernel. - MmCreateVirtualMapping (calls MmCreateVirtualMappingUnsafe). - MmCreateVirtualMappingUnsafe (for the kernel address space only). - MmSetPageProtect (unused on ARM). - MmCreateHyperspaceMapping. - MmDeleteHyperspaceMapping. - MmInitGlobalKernelPageDirectory. - MmInitPageDirectoryMap. - With the above, this means we now go well inside MmInit1: the PFN database is setup and works, memory areas are functional, and non-paged pool is fully working. - We currently hit a data abort during paged pool setup -- this is to be expected, since we don't have any exception handlers yet. These are coming up next -- we have to start handling crashes (and page faults). svn path=/trunk/; revision=32640
This commit is contained in:
@@ -61,12 +61,16 @@ L_ArmInit:
|
||||
.long ArmInit
|
||||
|
||||
.align 4
|
||||
.global BootStack
|
||||
BootStack:
|
||||
.space 0x4000
|
||||
BootStackEnd:
|
||||
.long 0
|
||||
|
||||
.section pagedata
|
||||
.global TranslationTableStart
|
||||
TranslationTableStart:
|
||||
|
||||
.global ArmTranslationTable
|
||||
ArmTranslationTable:
|
||||
.space 0x4000 // 0x00000000->0xFFFFFFFF
|
||||
@@ -74,19 +78,81 @@ ArmTranslationTable:
|
||||
.global BootTranslationTable
|
||||
BootTranslationTable:
|
||||
.space 0x0400 // 0x00000000->0x800FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00100000->0x801FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00200000->0x802FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00300000->0x803FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00400000->0x804FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00500000->0x805FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00600000->0x806FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00700000->0x807FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
|
||||
.global KernelTranslationTable
|
||||
KernelTranslationTable:
|
||||
.space 0x0400 // 0x00800000->0x808FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00900000->0x809FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00A00000->0x80AFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00B00000->0x80BFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00C00000->0x80CFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0x00D00000->0x80DFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
|
||||
.global FlatMapTranslationTable
|
||||
FlatMapTranslationTable:
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC00FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC01FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC02FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC03FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC04FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC05FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC06FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC07FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC08FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC09FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0AFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0BFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0CFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0DFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0EFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC0FFFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
|
||||
.global MasterTranslationTable
|
||||
MasterTranslationTable:
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC10FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
|
||||
.global HyperSpaceTranslationTable
|
||||
HyperSpaceTranslationTable:
|
||||
.space 0x0400 // 0xYYYYYYYY->0xC10FFFFF
|
||||
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
|
||||
|
||||
.global TranslationTableEnd
|
||||
TranslationTableEnd:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,12 +15,16 @@
|
||||
PARM_BOARD_CONFIGURATION_BLOCK ArmBoardBlock;
|
||||
ULONG BootDrive, BootPartition;
|
||||
VOID ArmPrepareForReactOS(IN BOOLEAN Setup);
|
||||
ADDRESS_RANGE ArmBoardMemoryMap[16];
|
||||
ULONG ArmBoardMemoryMapRangeCount;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
//
|
||||
// Remember the pointer
|
||||
//
|
||||
@@ -38,6 +42,22 @@ ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
|
||||
ASSERT((ArmBoardBlock->BoardType == MACH_TYPE_FEROCEON) ||
|
||||
(ArmBoardBlock->BoardType == MACH_TYPE_VERSATILE_PB));
|
||||
|
||||
//
|
||||
// Save data required for memory initialization
|
||||
//
|
||||
ArmBoardMemoryMapRangeCount = ArmBoardBlock->MemoryMapEntryCount;
|
||||
ASSERT(ArmBoardMemoryMapRangeCount != 0);
|
||||
ASSERT(ArmBoardMemoryMapRangeCount < 16);
|
||||
for (i = 0; i < ArmBoardMemoryMapRangeCount; i++)
|
||||
{
|
||||
//
|
||||
// Copy each entry
|
||||
//
|
||||
RtlCopyMemory(&ArmBoardMemoryMap[i],
|
||||
&ArmBoardBlock->MemoryMap[i],
|
||||
sizeof(ADDRESS_RANGE));
|
||||
}
|
||||
|
||||
//
|
||||
// Call FreeLDR's portable entrypoint with our command-line
|
||||
//
|
||||
|
||||
@@ -16,7 +16,10 @@ LdrPEGetExportByName(
|
||||
);
|
||||
|
||||
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
|
||||
PVOID AnsiData, OemData, UnicodeData, RegistryData;
|
||||
ULONG Drivers;
|
||||
PVOID AnsiData, OemData, UnicodeData, RegistryData, KernelData, HalData, DriverData[16];
|
||||
ULONG RegistrySize, AnsiSize, OemSize, UnicodeSize, KernelSize, HalSize, DriverSize[16];
|
||||
|
||||
/* MODULE MANAGEMENT **********************************************************/
|
||||
|
||||
PLOADER_MODULE
|
||||
@@ -101,19 +104,23 @@ FrLdrLoadModule(FILE *ModuleImage,
|
||||
if (!_stricmp(NameBuffer, "ansi.nls"))
|
||||
{
|
||||
AnsiData = (PVOID)NextModuleBase;
|
||||
AnsiSize = LocalModuleSize;
|
||||
}
|
||||
else if (!_stricmp(NameBuffer, "oem.nls"))
|
||||
{
|
||||
OemData = (PVOID)NextModuleBase;
|
||||
OemSize = LocalModuleSize;
|
||||
}
|
||||
else if (!_stricmp(NameBuffer, "casemap.nls"))
|
||||
{
|
||||
UnicodeData = (PVOID)NextModuleBase;
|
||||
UnicodeSize = LocalModuleSize;
|
||||
}
|
||||
else if (!(_stricmp(NameBuffer, "system")) ||
|
||||
!(_stricmp(NameBuffer, "system.hiv")))
|
||||
{
|
||||
RegistryData = (PVOID)NextModuleBase;
|
||||
RegistrySize = LocalModuleSize;
|
||||
}
|
||||
|
||||
/* Load the file image */
|
||||
@@ -548,6 +555,24 @@ FrLdrMapImage(IN FILE *Image,
|
||||
reactos_modules[ImageId].String = (ULONG_PTR)reactos_module_strings[ImageId];
|
||||
LoaderBlock.ModsCount++;
|
||||
|
||||
/* Detect kernel or HAL */
|
||||
if (!_stricmp(Name, "ntoskrnl.exe"))
|
||||
{
|
||||
KernelData = (PVOID)NextModuleBase;
|
||||
KernelSize = ImageSize;
|
||||
}
|
||||
else if (!_stricmp(Name, "hal.dll"))
|
||||
{
|
||||
HalData = (PVOID)NextModuleBase;
|
||||
HalSize = ImageSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
DriverData[Drivers] = (PVOID)NextModuleBase;
|
||||
DriverSize[Drivers] = ImageSize;
|
||||
Drivers++;
|
||||
}
|
||||
|
||||
/* Increase the next Load Base */
|
||||
NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
|
||||
|
||||
|
||||
@@ -47,19 +47,87 @@ C_ASSERT(MM_ALLOCATION_GRANULARITY >= PAGE_SIZE);
|
||||
//
|
||||
typedef struct _HARDWARE_PTE_ARM
|
||||
{
|
||||
ULONG Valid:1;
|
||||
ULONG Write:1;
|
||||
ULONG Owner:1;
|
||||
ULONG WriteThrough:1;
|
||||
ULONG CacheDisable:1;
|
||||
ULONG Accessed:1;
|
||||
ULONG Dirty:1;
|
||||
ULONG LargePage:1;
|
||||
ULONG Global:1;
|
||||
ULONG CopyOnWrite:1;
|
||||
ULONG Prototype: 1;
|
||||
ULONG reserved: 1;
|
||||
ULONG PageFrameNumber:20;
|
||||
union
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Unused:30;
|
||||
} Fault;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Ignored:2;
|
||||
ULONG Reserved:1;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored1:1;
|
||||
ULONG BaseAddress:22;
|
||||
} Coarse;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Reserved:1;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored:1;
|
||||
ULONG Access:2;
|
||||
ULONG Ignored1:8;
|
||||
ULONG BaseAddress:12;
|
||||
} Section;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Reserved:3;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored:3;
|
||||
ULONG BaseAddress:20;
|
||||
} Fine;
|
||||
} L1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Unused:30;
|
||||
} Fault;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Access1:2;
|
||||
ULONG Access2:2;
|
||||
ULONG Access3:2;
|
||||
ULONG Ignored:4;
|
||||
ULONG BaseAddress:16;
|
||||
} Large;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Access1:2;
|
||||
ULONG Access2:2;
|
||||
ULONG Access3:2;
|
||||
ULONG BaseAddress:20;
|
||||
} Small;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Ignored:4;
|
||||
ULONG BaseAddress:22;
|
||||
} Tiny;
|
||||
} L2;
|
||||
ULONG AsUlong;
|
||||
};
|
||||
} HARDWARE_PTE_ARM, *PHARDWARE_PTE_ARM;
|
||||
|
||||
typedef struct _MMPTE_SOFTWARE
|
||||
@@ -117,19 +185,87 @@ typedef struct _MMPTE_LIST
|
||||
|
||||
typedef struct _MMPTE_HARDWARE
|
||||
{
|
||||
ULONG Valid:1;
|
||||
ULONG Write:1;
|
||||
ULONG Owner:1;
|
||||
ULONG WriteThrough:1;
|
||||
ULONG CacheDisable:1;
|
||||
ULONG Accessed:1;
|
||||
ULONG Dirty:1;
|
||||
ULONG LargePage:1;
|
||||
ULONG Global:1;
|
||||
ULONG CopyOnWrite:1;
|
||||
ULONG Prototype:1;
|
||||
ULONG reserved:1;
|
||||
ULONG PageFrameNumber:20;
|
||||
union
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Unused:30;
|
||||
} Fault;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Ignored:2;
|
||||
ULONG Reserved:1;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored1:1;
|
||||
ULONG BaseAddress:22;
|
||||
} Coarse;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Reserved:1;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored:1;
|
||||
ULONG Access:2;
|
||||
ULONG Ignored1:8;
|
||||
ULONG BaseAddress:12;
|
||||
} Section;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Reserved:3;
|
||||
ULONG Domain:4;
|
||||
ULONG Ignored:3;
|
||||
ULONG BaseAddress:20;
|
||||
} Fine;
|
||||
} L1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Unused:30;
|
||||
} Fault;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Access1:2;
|
||||
ULONG Access2:2;
|
||||
ULONG Access3:2;
|
||||
ULONG Ignored:4;
|
||||
ULONG BaseAddress:16;
|
||||
} Large;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Access1:2;
|
||||
ULONG Access2:2;
|
||||
ULONG Access3:2;
|
||||
ULONG BaseAddress:20;
|
||||
} Small;
|
||||
struct
|
||||
{
|
||||
ULONG Type:2;
|
||||
ULONG Buffered:1;
|
||||
ULONG Cached:1;
|
||||
ULONG Access0:2;
|
||||
ULONG Ignored:4;
|
||||
ULONG BaseAddress:22;
|
||||
} Tiny;
|
||||
} L2;
|
||||
ULONG AsUlong;
|
||||
};
|
||||
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
|
||||
|
||||
//
|
||||
|
||||
@@ -174,5 +174,6 @@ KeFlushTb(
|
||||
);
|
||||
|
||||
#define KeArchInitThreadWithContext KeArmInitThreadWithContext
|
||||
#define KiSystemStartupReal KiSystemStartup
|
||||
|
||||
#endif
|
||||
|
||||
@@ -113,6 +113,7 @@ typedef struct _ARM_TRANSLATION_TABLE
|
||||
typedef struct _ARM_COARSE_PAGE_TABLE
|
||||
{
|
||||
ARM_PTE Pte[256];
|
||||
ULONG Padding[768];
|
||||
} ARM_COARSE_PAGE_TABLE, *PARM_COARSE_PAGE_TABLE;
|
||||
|
||||
typedef enum _ARM_L1_PTE_TYPE
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//
|
||||
// UART Registers
|
||||
//
|
||||
#define UART_BASE (void*)0xc00f1000 /* HACK: freeldr mapped it here */
|
||||
#define UART_BASE (void*)0xe00f1000 /* HACK: freeldr mapped it here */
|
||||
|
||||
#define UART_PL01x_DR (UART_BASE + 0x00)
|
||||
#define UART_PL01x_RSR (UART_BASE + 0x04)
|
||||
|
||||
@@ -771,7 +771,7 @@ KiRosAllocateNtDescriptor(IN TYPE_OF_MEMORY MemoryType,
|
||||
if (MdBlock)
|
||||
{
|
||||
/* If it contains our limit as well, break out early */
|
||||
if ((MdBlock->PageCount + MdBlock->BasePage) > AlignedLimit) break;
|
||||
if ((MdBlock->PageCount + MdBlock->BasePage) >= AlignedLimit) break;
|
||||
}
|
||||
|
||||
/* Loop the memory list */
|
||||
|
||||
+400
-32
@@ -20,6 +20,29 @@
|
||||
while (TRUE); \
|
||||
}
|
||||
|
||||
//
|
||||
// Take 0x80812345 and extract:
|
||||
// PTE_BASE[0x808][0x12]
|
||||
//
|
||||
#define MiGetPteAddress(x) \
|
||||
(PMMPTE)(PTE_BASE + (((ULONG)(x) >> 20) << 12) + ((((ULONG)(x) >> 12) & 0xFF) << 2))
|
||||
|
||||
#define MiGetPdeAddress(x) \
|
||||
(PMMPTE)(PDE_BASE + (((ULONG)(x) >> 20) << 2))
|
||||
|
||||
#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
|
||||
|
||||
#define PTE_BASE 0xC0000000
|
||||
#define PDE_BASE 0xC1000000
|
||||
#define HYPER_SPACE ((PVOID)0xC1100000)
|
||||
|
||||
ULONG MmGlobalKernelPageDirectory[1024];
|
||||
MMPTE MiArmTemplatePte, MiArmTemplatePde;
|
||||
|
||||
VOID
|
||||
KiFlushSingleTb(IN BOOLEAN Invalid,
|
||||
IN PVOID Virtual);
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
@@ -71,10 +94,9 @@ PULONG
|
||||
MmGetPageDirectory(VOID)
|
||||
{
|
||||
//
|
||||
// TODO
|
||||
// Return the TTB
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
return (PULONG)KeArmTranslationTableRegisterGet().AsUlong;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,10 +118,65 @@ NTAPI
|
||||
MmDeletePageTable(IN PEPROCESS Process,
|
||||
IN PVOID Address)
|
||||
{
|
||||
PMMPTE PointerPde;
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Not valid for kernel addresses
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
DPRINT1("MmDeletePageTable(%p, %p)\n", Process, Address);
|
||||
ASSERT(Address < MmSystemRangeStart);
|
||||
|
||||
//
|
||||
// Check if this is for a different process
|
||||
//
|
||||
if ((Process) && (Process != PsGetCurrentProcess()))
|
||||
{
|
||||
//
|
||||
// TODO
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the PDE
|
||||
//
|
||||
PointerPde = MiGetPdeAddress(Address);
|
||||
|
||||
//
|
||||
// On ARM, we use a section mapping for the original low-memory mapping
|
||||
//
|
||||
if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
|
||||
{
|
||||
//
|
||||
// Make sure it's valid
|
||||
//
|
||||
ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
|
||||
}
|
||||
|
||||
//
|
||||
// Clear the PDE
|
||||
//
|
||||
PointerPde->u.Hard.AsUlong = 0;
|
||||
ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
|
||||
|
||||
//
|
||||
// Check if this is a kernel PDE
|
||||
//
|
||||
if ((PointerPde >= (PMMPTE)PTE_BASE) && (PointerPde < (PMMPTE)PTE_BASE + (1024 * 1024)))
|
||||
{
|
||||
//
|
||||
// Invalidate the TLB entry
|
||||
//
|
||||
KiFlushSingleTb(TRUE, Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Process PDE, unmap it from hyperspace (will also invalidate TLB entry)
|
||||
//
|
||||
MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(PointerPde));
|
||||
}
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
@@ -215,11 +292,38 @@ NTAPI
|
||||
MmIsPagePresent(IN PEPROCESS Process,
|
||||
IN PVOID Address)
|
||||
{
|
||||
PMMPTE Pte;
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Check if this is for a different process
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
if ((Process) && (Process != PsGetCurrentProcess()))
|
||||
{
|
||||
//
|
||||
// TODO
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the PDE
|
||||
//
|
||||
Pte = MiGetPdeAddress(Address);
|
||||
if (Pte->u.Hard.L1.Fault.Type != FaultPte)
|
||||
{
|
||||
//
|
||||
// Get the PTE
|
||||
//
|
||||
Pte = MiGetPteAddress(Address);
|
||||
}
|
||||
|
||||
//
|
||||
// Return whether or not it's valid
|
||||
//
|
||||
return (Pte->u.Hard.L1.Fault.Type != FaultPte);
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
@@ -237,15 +341,107 @@ MmIsPageSwapEntry(IN PEPROCESS Process,
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMappingForKernel(IN PVOID Address,
|
||||
IN ULONG flProtect,
|
||||
IN PPFN_TYPE Pages,
|
||||
IN ULONG Protection,
|
||||
IN PPFN_NUMBER Pages,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
PMMPTE PointerPte, LastPte, PointerPde, LastPde;
|
||||
MMPTE TempPte, TempPde;
|
||||
NTSTATUS Status;
|
||||
PFN_NUMBER Pfn;
|
||||
DPRINT1("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n",
|
||||
Address, Protection, *Pages, PageCount);
|
||||
ASSERT(Address >= MmSystemRangeStart);
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Get our templates
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
TempPte = MiArmTemplatePte;
|
||||
TempPde = MiArmTemplatePde;
|
||||
|
||||
//
|
||||
// Check if we have PDEs for this region
|
||||
//
|
||||
PointerPde = MiGetPdeAddress(Address);
|
||||
LastPde = PointerPde + (PageCount / 256);
|
||||
while (PointerPde <= LastPde)
|
||||
{
|
||||
//
|
||||
// Check if we need to allocate the PDE
|
||||
//
|
||||
if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
|
||||
{
|
||||
//
|
||||
// Request a page
|
||||
//
|
||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
//
|
||||
// Setup the PFN
|
||||
//
|
||||
TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn << PAGE_SHIFT) >> CPT_SHIFT;
|
||||
|
||||
//
|
||||
// Write the PDE
|
||||
//
|
||||
ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
|
||||
ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
|
||||
*PointerPde = TempPde;
|
||||
|
||||
//
|
||||
// Get the PTE for this 1MB region
|
||||
//
|
||||
PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
|
||||
|
||||
//
|
||||
// Write the PFN of the PDE
|
||||
//
|
||||
TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
|
||||
|
||||
//
|
||||
// Write the PTE
|
||||
//
|
||||
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
|
||||
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
|
||||
*PointerPte = TempPte;
|
||||
}
|
||||
|
||||
//
|
||||
// Next
|
||||
//
|
||||
PointerPde++;
|
||||
}
|
||||
|
||||
//
|
||||
// Get start and end address and loop each PTE
|
||||
//
|
||||
PointerPte = MiGetPteAddress(Address);
|
||||
LastPte = PointerPte + PageCount - 1;
|
||||
while (PointerPte <= LastPte)
|
||||
{
|
||||
//
|
||||
// Set the PFN
|
||||
//
|
||||
TempPte.u.Hard.L2.Small.BaseAddress = *Pages++;
|
||||
|
||||
//
|
||||
// Write the PTE
|
||||
//
|
||||
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
|
||||
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
|
||||
*PointerPte = TempPte;
|
||||
|
||||
//
|
||||
// Next
|
||||
//
|
||||
PointerPte++;
|
||||
}
|
||||
|
||||
//
|
||||
// All done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
@@ -265,10 +461,27 @@ NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMappingUnsafe(IN PEPROCESS Process,
|
||||
IN PVOID Address,
|
||||
IN ULONG flProtect,
|
||||
IN ULONG Protection,
|
||||
IN PPFN_TYPE Pages,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
DPRINT1("MmCreateVirtualMappingUnsafe(%p %x, %x, %x, %d)\n",
|
||||
Process, Address, Protection, *Pages, PageCount);
|
||||
|
||||
//
|
||||
// Are we only handling the kernel?
|
||||
//
|
||||
if (!Process)
|
||||
{
|
||||
//
|
||||
// Call the kernel version
|
||||
//
|
||||
return MmCreateVirtualMappingForKernel(Address,
|
||||
Protection,
|
||||
Pages,
|
||||
PageCount);
|
||||
}
|
||||
|
||||
//
|
||||
// TODO
|
||||
//
|
||||
@@ -280,15 +493,33 @@ NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMapping(IN PEPROCESS Process,
|
||||
IN PVOID Address,
|
||||
IN ULONG flProtect,
|
||||
IN ULONG Protection,
|
||||
IN PPFN_TYPE Pages,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
ULONG i;
|
||||
DPRINT1("MmCreateVirtualMapping(%p %x, %x, %x, %d)\n",
|
||||
Process, Address, Protection, *Pages, PageCount);
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Loop each page
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
for (i = 0; i < PageCount; i++)
|
||||
{
|
||||
//
|
||||
// Make sure the page is marked as in use
|
||||
//
|
||||
ASSERT(MmIsPageInUse(Pages[i]));
|
||||
}
|
||||
|
||||
//
|
||||
// Call the unsafe version
|
||||
//
|
||||
return MmCreateVirtualMappingUnsafe(Process,
|
||||
Address,
|
||||
Protection,
|
||||
Pages,
|
||||
PageCount);
|
||||
}
|
||||
|
||||
ULONG
|
||||
@@ -307,12 +538,12 @@ VOID
|
||||
NTAPI
|
||||
MmSetPageProtect(IN PEPROCESS Process,
|
||||
IN PVOID Address,
|
||||
IN ULONG flProtect)
|
||||
IN ULONG Protection)
|
||||
{
|
||||
//
|
||||
// TODO
|
||||
// We don't enforce any protection on the pages -- they are all RWX
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -335,34 +566,124 @@ PVOID
|
||||
NTAPI
|
||||
MmCreateHyperspaceMapping(IN PFN_TYPE Page)
|
||||
{
|
||||
PMMPTE PointerPte, FirstPte, LastPte;
|
||||
MMPTE TempPte;
|
||||
PVOID Address;
|
||||
DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Page);
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Loop hyperspace PTEs (1MB)
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
FirstPte = PointerPte = MiGetPteAddress(HYPER_SPACE);
|
||||
LastPte = PointerPte + 256;
|
||||
while (PointerPte <= LastPte)
|
||||
{
|
||||
//
|
||||
// Find a free slot
|
||||
//
|
||||
if (PointerPte->u.Hard.L2.Fault.Type == FaultPte)
|
||||
{
|
||||
//
|
||||
// Use this entry
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Try the next one
|
||||
//
|
||||
PointerPte++;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if we didn't find anything
|
||||
//
|
||||
if (PointerPte > LastPte) return NULL;
|
||||
|
||||
//
|
||||
// Create the mapping
|
||||
//
|
||||
TempPte = MiArmTemplatePte;
|
||||
TempPte.u.Hard.L2.Small.BaseAddress = Page;
|
||||
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
|
||||
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
|
||||
*PointerPte = TempPte;
|
||||
|
||||
//
|
||||
// Return the address
|
||||
//
|
||||
Address = HYPER_SPACE + ((PointerPte - FirstPte) * PAGE_SIZE);
|
||||
KiFlushSingleTb(FALSE, Address);
|
||||
DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Address);
|
||||
return Address;
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmDeleteHyperspaceMapping(IN PVOID Address)
|
||||
{
|
||||
PFN_TYPE Pfn = {0};
|
||||
|
||||
PFN_TYPE Pfn;
|
||||
PMMPTE PointerPte;
|
||||
DPRINT1("MmDeleteHyperspaceMapping(%lx)\n", Address);
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Get the PTE
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
PointerPte = MiGetPteAddress(Address);
|
||||
ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
|
||||
|
||||
//
|
||||
// Save the PFN
|
||||
//
|
||||
Pfn = PointerPte->u.Hard.L2.Small.BaseAddress;
|
||||
|
||||
//
|
||||
// Destroy the PTE
|
||||
//
|
||||
PointerPte->u.Hard.AsUlong = 0;
|
||||
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
|
||||
|
||||
//
|
||||
// Flush the TLB entry and return the PFN
|
||||
//
|
||||
KiFlushSingleTb(TRUE, Address);
|
||||
return Pfn;
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmInitGlobalKernelPageDirectory(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
PULONG CurrentPageDirectory = (PULONG)PDE_BASE;
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Good place to setup template PTE/PDEs.
|
||||
// We are lazy and pick a known-good PTE
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
MiArmTemplatePte = *MiGetPteAddress(0x80000000);
|
||||
MiArmTemplatePde = *MiGetPdeAddress(0x80000000);
|
||||
|
||||
//
|
||||
// Loop the 2GB of address space which belong to the kernel
|
||||
//
|
||||
for (i = MiGetPdeOffset(MmSystemRangeStart); i < 1024; i++)
|
||||
{
|
||||
//
|
||||
// Check if we have an entry for this already
|
||||
//
|
||||
if ((i != MiGetPdeOffset(PTE_BASE)) &&
|
||||
(i != MiGetPdeOffset(HYPER_SPACE)) &&
|
||||
(!MmGlobalKernelPageDirectory[i]) &&
|
||||
(CurrentPageDirectory[i]))
|
||||
{
|
||||
//
|
||||
// We don't, link it in our global page directory
|
||||
//
|
||||
MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ULONG
|
||||
@@ -380,8 +701,55 @@ VOID
|
||||
NTAPI
|
||||
MiInitPageDirectoryMap(VOID)
|
||||
{
|
||||
MEMORY_AREA* MemoryArea = NULL;
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||
PVOID BaseAddress;
|
||||
NTSTATUS Status;
|
||||
DPRINT1("MiInitPageDirectoryMap()\n");
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Create memory area for the PTE area
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
BoundaryAddressMultiple.QuadPart = 0;
|
||||
BaseAddress = (PVOID)PTE_BASE;
|
||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_SYSTEM,
|
||||
&BaseAddress,
|
||||
0x1000000,
|
||||
PAGE_READWRITE,
|
||||
&MemoryArea,
|
||||
TRUE,
|
||||
0,
|
||||
BoundaryAddressMultiple);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
//
|
||||
// Create memory area for the PDE area
|
||||
//
|
||||
BaseAddress = (PVOID)PDE_BASE;
|
||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_SYSTEM,
|
||||
&BaseAddress,
|
||||
0x100000,
|
||||
PAGE_READWRITE,
|
||||
&MemoryArea,
|
||||
TRUE,
|
||||
0,
|
||||
BoundaryAddressMultiple);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
//
|
||||
// And finally, hyperspace
|
||||
//
|
||||
BaseAddress = (PVOID)HYPER_SPACE;
|
||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_SYSTEM,
|
||||
&BaseAddress,
|
||||
PAGE_SIZE,
|
||||
PAGE_READWRITE,
|
||||
&MemoryArea,
|
||||
TRUE,
|
||||
0,
|
||||
BoundaryAddressMultiple);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
}
|
||||
|
||||
@@ -347,9 +347,7 @@ MiGetLastKernelAddress(VOID)
|
||||
NextEntry = NextEntry->Flink)
|
||||
{
|
||||
Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
|
||||
if (Md->MemoryType == LoaderBootDriver ||
|
||||
Md->MemoryType == LoaderSystemCode ||
|
||||
Md->MemoryType == LoaderHalCode)
|
||||
if (Md->MemoryType != LoaderFree)
|
||||
{
|
||||
if (Md->BasePage+Md->PageCount > LastKrnlPhysAddr)
|
||||
LastKrnlPhysAddr = Md->BasePage+Md->PageCount;
|
||||
@@ -432,10 +430,13 @@ MmInit1(VOID)
|
||||
MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MiNonPagedPoolStart +
|
||||
MiNonPagedPoolLength);
|
||||
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
|
||||
|
||||
/* Dump kernel memory layout */
|
||||
MiDbgKernelLayout();
|
||||
|
||||
/* Initialize the page list */
|
||||
MmInitializePageList();
|
||||
|
||||
/* Unmap low memory */
|
||||
MmDeletePageTable(NULL, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user