Author: ros-arm-bringup
Date: Mon Mar 10 12:27:14 2008
New Revision: 32640
URL:
http://svn.reactos.org/svn/reactos?rev=3D32640&view=3Drev
Log:
ARM Port Memory Management Checkpoint:
- Implemented and defined the MMU-OS architecture for the ARM port. The det=
ails are too long for a commit message, but we have decided to replicate th=
e 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!) fo=
r PDE vs PTEs! We emulate the behavior however (which adds a small performa=
nce 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 mem=
ory layout (see comments for some lengthier explenations)
- Allocations made by FreeLDR for loading ReactOS are now made from a "shar=
ed 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 archit=
ecture! 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 ke=
rnel:
- 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 databas=
e is setup and works, memory areas are functional, and non-paged pool is fu=
lly working.
- We currently hit a data abort during paged pool setup -- this is to be ex=
pected, since we don't have any exception handlers yet. These are coming up=
next -- we have to start handling crashes (and page faults).
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s
trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c
trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c
trunk/reactos/include/ndk/arm/mmtypes.h
trunk/reactos/ntoskrnl/include/internal/arm/ke.h
trunk/reactos/ntoskrnl/include/internal/arm/mm.h
trunk/reactos/ntoskrnl/ke/arm/arm_kprintf.c
trunk/reactos/ntoskrnl/ke/freeldr.c
trunk/reactos/ntoskrnl/mm/arm/stubs.c
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/=
arch/arm/boot.s?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s Mon Mar 10 12:27:14 =
2008
@@ -61,12 +61,16 @@
.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 @@
.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:
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/=
arch/arm/loader.c?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c Mon Mar 10 12:27:1=
4 2008
@@ -13,7 +13,15 @@
#include <internal/arm/mm.h>
#include <internal/arm/intrin_i.h>
=
+#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SH=
IFT)
+
/* GLOBALS ***************************************************************=
*****/
+
+typedef struct _BIOS_MEMORY_DESCRIPTOR
+{
+ ULONG BlockBase;
+ ULONG BlockSize;
+} BIOS_MEMORY_DESCRIPTOR, *PBIOS_MEMORY_DESCRIPTOR;
=
ULONG PageDirectoryStart, PageDirectoryEnd;
PLOADER_PARAMETER_BLOCK ArmLoaderBlock;
@@ -24,11 +32,23 @@
CHAR ArmNtBootPath[64];
PNLS_DATA_BLOCK ArmNlsDataBlock;
PLOADER_PARAMETER_EXTENSION ArmExtension;
+BIOS_MEMORY_DESCRIPTOR ArmBoardMemoryDescriptors[16] =3D {{0}};
+PBIOS_MEMORY_DESCRIPTOR ArmBoardMemoryList =3D ArmBoardMemoryDescriptors;
+ULONG NumberDescriptors =3D 0;
+MEMORY_DESCRIPTOR MDArray[16] =3D {{0}};
+ULONG ArmSharedHeapSize;
+PCHAR ArmSharedHeap;
+
+extern ADDRESS_RANGE ArmBoardMemoryMap[16];
+extern ULONG ArmBoardMemoryMapRangeCount;
extern ARM_TRANSLATION_TABLE ArmTranslationTable;
-extern ARM_COARSE_PAGE_TABLE BootTranslationTable, KernelTranslationTable;
+extern ARM_COARSE_PAGE_TABLE BootTranslationTable, KernelTranslationTable,=
FlatMapTranslationTable, MasterTranslationTable, HyperSpaceTranslationTabl=
e;
extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
extern ULONG_PTR KernelBase;
-extern ULONG_PTR AnsiData, OemData, UnicodeData, RegistryData;
+extern ULONG_PTR AnsiData, OemData, UnicodeData, RegistryData, KernelData,=
HalData, DriverData[16];
+extern ULONG RegistrySize, AnsiSize, OemSize, UnicodeSize, KernelSize, Hal=
Size, DriverSize[16];
+extern ULONG Drivers;
+extern ULONG BootStack, TranslationTableStart, TranslationTableEnd;
=
ULONG SizeBits[] =3D
{
@@ -59,9 +79,614 @@
//
// Where to map the serial port
//
-#define UART_VIRTUAL 0xC0000000
+#define UART_VIRTUAL 0xE0000000
+
+#define PTE_BASE 0xC0000000
+#define PDE_BASE 0xC1000000
+#define HYPER_SPACE 0xC1100000
+
+//
+// Take 0x80812345 and extract:
+// PTE_BASE[0x808][0x12]
+//
+#define MiAddressToPte(x) \
+ (PTE_BASE + (((x) >> 20) << 12) + ((((x) >> 12) & 0xFF)
<< 2))
+
+#define MiAddressToPde(x) \
+ (PDE_BASE + (((x) >> 20) << 2))
=
/* FUNCTIONS *************************************************************=
*****/
+
+PVOID
+ArmAllocateFromSharedHeap(IN ULONG Size)
+{
+ PVOID Buffer;
+
+ //
+ // Allocate from the shared heap
+ //
+ Buffer =3D &ArmSharedHeap[ArmSharedHeapSize];
+ ArmSharedHeapSize +=3D Size;
+ return Buffer;
+}
+
+PMEMORY_ALLOCATION_DESCRIPTOR
+NTAPI
+ArmAllocateMemoryDescriptor(VOID)
+{
+ //
+ // Allocate a descriptor from the heap
+ //
+ return ArmAllocateFromSharedHeap(sizeof(MEMORY_ALLOCATION_DESCRIPTOR));
+}
+
+VOID
+NTAPI
+ArmAddBoardMemoryDescriptor(IN ULONG Address,
+ IN ULONG Size)
+{
+ PBIOS_MEMORY_DESCRIPTOR BiosBlock =3D ArmBoardMemoryList;
+ =
+ //
+ // Loop board DRAM configuration
+ //
+ while (BiosBlock->BlockSize > 0)
+ {
+ /* Check if we've found a matching head block */
+ if (Address + Size =3D=3D BiosBlock->BlockBase)
+ {
+ /* Simply enlarge and rebase it */
+ BiosBlock->BlockBase =3D Address;
+ BiosBlock->BlockSize +=3D Size;
+ break;
+ }
+ =
+ /* Check if we've found a matching tail block */
+ if (Address =3D=3D (BiosBlock->BlockBase + BiosBlock->BlockSize))
+ {
+ /* Simply enlarge it */
+ BiosBlock->BlockSize +=3D Size;
+ break;
+ }
+ =
+ /* Nothing suitable found, try the next block */
+ BiosBlock++;
+ }
+ =
+ /* No usable blocks found, found a free block instead */
+ if (!BiosBlock->BlockSize)
+ {
+ /* Write our data */
+ BiosBlock->BlockBase =3D Address;
+ BiosBlock->BlockSize =3D Size;
+ =
+ /* Create a new block and mark it as the end of the array */
+ BiosBlock++;
+ BiosBlock->BlockBase =3D BiosBlock->BlockSize =3D 0L;
+ }
+}
+
+VOID
+NTAPI
+ArmBuildBoardMemoryMap(VOID)
+{
+ ULONG BlockBegin, BlockEnd;
+ ULONG j;
+ =
+ /* Loop the BIOS Memory Map */
+ for (j =3D 0; j < ArmBoardMemoryMapRangeCount; j++)
+ {
+ /* Get the start and end addresses */
+ BlockBegin =3D ArmBoardMemoryMap[j].BaseAddrLow;
+ BlockEnd =3D ArmBoardMemoryMap[j].BaseAddrLow + ArmBoardMemoryMap[=
j].LengthLow - 1;
+ =
+ /* Make sure this isn't a > 4GB descriptor */
+ if (!ArmBoardMemoryMap[j].BaseAddrHigh)
+ {
+ /* Make sure we don't overflow */
+ if (BlockEnd < BlockBegin) BlockEnd =3D 0xFFFFFFFF;
+ =
+ /* Check if this is free memory */
+ if (ArmBoardMemoryMap[j].Type =3D=3D 1)
+ {
+ /* Add it to our BIOS descriptors */
+ ArmAddBoardMemoryDescriptor(BlockBegin, BlockEnd - BlockBe=
gin + 1);
+ }
+ }
+ }
+}
+
+NTSTATUS
+NTAPI
+ArmConfigureArcDescriptor(IN ULONG PageBegin,
+ IN ULONG PageEnd,
+ IN TYPE_OF_MEMORY MemoryType)
+{
+ ULONG i;
+ ULONG BlockBegin, BlockEnd;
+ MEMORY_TYPE BlockType;
+ BOOLEAN Combined =3D FALSE;
+ =
+ /* If this descriptor seems bogus, just return */
+ if (PageEnd <=3D PageBegin) return STATUS_SUCCESS;
+ =
+ /* Loop every ARC descriptor, trying to find one we can modify */
+ for (i =3D 0; i < NumberDescriptors; i++)
+ {
+ /* Get its settings */
+ BlockBegin =3D MDArray[i].BasePage;
+ BlockEnd =3D MDArray[i].BasePage + MDArray[i].PageCount;
+ BlockType =3D MDArray[i].MemoryType;
+ =
+ /* Check if we can fit inside this block */
+ if (BlockBegin < PageBegin)
+ {
+ /* Check if we are larger then it */
+ if ((BlockEnd > PageBegin) && (BlockEnd <=3D PageEnd))
+ {
+ /* Make it end where we start */
+ BlockEnd =3D PageBegin;
+ }
+ =
+ /* Check if it ends after we do */
+ if (BlockEnd > PageEnd)
+ {
+ /* Make sure we can allocate a descriptor */
+ if (NumberDescriptors =3D=3D 60) return ENOMEM;
+ =
+ /* Create a descriptor for whatever memory we're not part =
of */
+ MDArray[NumberDescriptors].MemoryType =3D BlockType;
+ MDArray[NumberDescriptors].BasePage =3D PageEnd;
+ MDArray[NumberDescriptors].PageCount =3D BlockEnd - PageE=
nd;
+ NumberDescriptors++;
+ =
+ /* The next block ending is now where we begin */
+ BlockEnd =3D PageBegin;
+ }
+ }
+ else
+ {
+ /* Check if the blog begins inside our range */
+ if (BlockBegin < PageEnd)
+ {
+ /* Check if it ends before we do */
+ if (BlockEnd < PageEnd)
+ {
+ /* Then make it disappear */
+ BlockEnd =3D BlockBegin;
+ }
+ else
+ {
+ /* Otherwise make it start where we end */
+ BlockBegin =3D PageEnd;
+ }
+ }
+ }
+ =
+ /* Check if the block matches us, and we haven't tried combining y=
et */
+ if ((BlockType =3D=3D MemoryType) && !(Combined))
+ {
+ /* Check if it starts where we end */
+ if (BlockBegin =3D=3D PageEnd)
+ {
+ /* Make it start with us, and combine us */
+ BlockBegin =3D PageBegin;
+ Combined =3D TRUE;
+ }
+ else if (BlockEnd =3D=3D PageBegin)
+ {
+ /* Otherwise, it ends where we begin, combine its ending */
+ BlockEnd =3D PageEnd;
+ Combined =3D TRUE;
+ }
+ }
+ =
+ /* Check the original block data matches with what we came up with=
*/
+ if ((MDArray[i].BasePage =3D=3D BlockBegin) &&
+ (MDArray[i].PageCount =3D=3D BlockEnd - BlockBegin))
+ {
+ /* Then skip it */
+ continue;
+ }
+ =
+ /* Otherwise, set our new settings for this block */
+ MDArray[i].BasePage =3D BlockBegin;
+ MDArray[i].PageCount =3D BlockEnd - BlockBegin;
+ =
+ /* Check if we are killing the block */
+ if (BlockBegin =3D=3D BlockEnd)
+ {
+ /* Delete this block and restart the loop properly */
+ NumberDescriptors--;
+ if (i < NumberDescriptors) MDArray[i] =3D MDArray[NumberDescri=
ptors];
+ i--;
+ }
+ }
+ =
+ /* If we got here without combining, we need to allocate a new block */
+ if (!(Combined) && (MemoryType < LoaderMaximum))
+ {
+ /* Make sure there's enough descriptors */
+ if (NumberDescriptors =3D=3D 60) return ENOMEM;
+ =
+ /* Allocate a new block with our data */
+ MDArray[NumberDescriptors].MemoryType =3D MemoryType;
+ MDArray[NumberDescriptors].BasePage =3D PageBegin;
+ MDArray[NumberDescriptors].PageCount =3D PageEnd - PageBegin;
+ NumberDescriptors++;
+ }
+ =
+ /* Changes complete, return success */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ArmBuildOsMemoryMap(VOID)
+{
+ PBIOS_MEMORY_DESCRIPTOR MdBlock;
+ ULONG BlockStart, BlockEnd, BiasedStart, BiasedEnd, PageStart, PageEnd;
+ NTSTATUS Status =3D STATUS_SUCCESS;
+ =
+ /* Loop the BIOS Memory Descriptor List */
+ MdBlock =3D ArmBoardMemoryList;
+ while (MdBlock->BlockSize)
+ {
+ /* Get the statrt and end addresses */
+ BlockStart =3D MdBlock->BlockBase;
+ BlockEnd =3D BlockStart + MdBlock->BlockSize - 1;
+ =
+ /* Align them to page boundaries */
+ BiasedStart =3D BlockStart & (PAGE_SIZE - 1);
+ if (BiasedStart) BlockStart =3D BlockStart + PAGE_SIZE - BiasedSta=
rt;
+ BiasedEnd =3D (BlockEnd + 1) & (ULONG)(PAGE_SIZE - 1);
+ if (BiasedEnd) BlockEnd -=3D BiasedEnd;
+ =
+ /* Get the actual page numbers */
+ PageStart =3D BlockStart >> PAGE_SHIFT;
+ PageEnd =3D (BlockEnd + 1) >> PAGE_SHIFT;
+
+ /* Check if we did any alignment */
+ if (BiasedStart)
+ {
+ /* Mark that region as reserved */
+ Status =3D ArmConfigureArcDescriptor(PageStart - 1,
+ PageStart,
+ MemorySpecialMemory);
+ if (Status !=3D STATUS_SUCCESS) break;
+ }
+ =
+ /* Check if we did any alignment */
+ if (BiasedEnd)
+ {
+ /* Mark that region as reserved */
+ Status =3D ArmConfigureArcDescriptor(PageEnd - 1,
+ PageEnd,
+ MemorySpecialMemory);
+ if (Status !=3D STATUS_SUCCESS) break;
+ }
+ =
+ /* It is, mark the memory a free */
+ Status =3D ArmConfigureArcDescriptor(PageStart,
+ PageEnd,
+ LoaderFree);
+ =
+ /* If we failed, break out, otherwise, go to the next BIOS block */
+ if (Status !=3D STATUS_SUCCESS) break;
+ MdBlock++;
+ }
+ =
+ /* Return error code */
+ return Status;
+}
+
+VOID
+NTAPI
+ArmInsertMemoryDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
+{
+ PLIST_ENTRY ListHead, PreviousEntry, NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor =3D NULL, NextDescriptor =3D =
NULL;
+ =
+ /* Loop the memory descriptor list */
+ ListHead =3D &ArmLoaderBlock->MemoryDescriptorListHead;
+ PreviousEntry =3D ListHead;
+ NextEntry =3D ListHead->Flink;
+ while (NextEntry !=3D ListHead)
+ {
+ /* Get the current descriptor and check if it's below ours */
+ NextDescriptor =3D CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+ if (NewDescriptor->BasePage < NextDescriptor->BasePage) break;
+ =
+ /* It isn't, save the previous entry and descriptor, and try again=
*/
+ PreviousEntry =3D NextEntry;
+ Descriptor =3D NextDescriptor;
+ NextEntry =3D NextEntry->Flink;
+ }
+ =
+ /* So we found the right spot to insert. Is this free memory? */
+ if (NewDescriptor->MemoryType !=3D LoaderFree)
+ {
+ /* It isn't, so insert us before the last descriptor */
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+ else
+ {
+ /* We're free memory. Check if the entry we found is also free mem=
ory */
+ if ((PreviousEntry !=3D ListHead) &&
+ ((Descriptor->MemoryType =3D=3D LoaderFree) ||
+ (Descriptor->MemoryType =3D=3D LoaderReserve)) &&
+ ((Descriptor->BasePage + Descriptor->PageCount) =3D=3D
+ NewDescriptor->BasePage))
+ {
+ /* It's free memory, and we're right after it. Enlarge that bl=
ock */
+ Descriptor->PageCount +=3D NewDescriptor->PageCount;
+ NewDescriptor =3D Descriptor;
+ }
+ else
+ {
+ /* Our range scan't be combined, so just insert us separately =
*/
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+ =
+ /* Check if we merged with an existing free memory block */
+ if ((NextEntry !=3D ListHead) &&
+ ((NextDescriptor->MemoryType =3D=3D LoaderFree) ||
+ (NextDescriptor->MemoryType =3D=3D LoaderReserve)) &&
+ ((NewDescriptor->BasePage + NewDescriptor->PageCount) =3D=3D
+ NextDescriptor->BasePage))
+ {
+ /* Update our own block */
+ NewDescriptor->PageCount +=3D NextDescriptor->PageCount;
+ =
+ /* Remove the next block */
+ RemoveEntryList(&NextDescriptor->ListEntry);
+ }
+ }
+}
+
+NTSTATUS
+NTAPI
+ArmBuildMemoryDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor,
+ IN MEMORY_TYPE MemoryType,
+ IN ULONG BasePage,
+ IN ULONG PageCount)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor, NextDescriptor =3D NULL;
+ LONG Delta;
+ TYPE_OF_MEMORY CurrentType;
+ BOOLEAN UseNext;
+ =
+ /* Check how many pages we'll be consuming */
+ Delta =3D BasePage - MemoryDescriptor->BasePage;
+ if (!(Delta) && (PageCount =3D=3D MemoryDescriptor->PageCount))
+ {
+ /* We can simply convert the current descriptor into our new type =
*/
+ MemoryDescriptor->MemoryType =3D MemoryType;
+ }
+ else
+ {
+ /* Get the current memory type of the descriptor, and reserve it */
+ CurrentType =3D MemoryDescriptor->MemoryType;
+ MemoryDescriptor->MemoryType =3D LoaderSpecialMemory;
+ =
+ /* Check if we'll need another descriptor for what's left of memor=
y */
+ UseNext =3D ((BasePage !=3D MemoryDescriptor->BasePage) &&
+ (Delta + PageCount !=3D MemoryDescriptor->PageCount));
+ =
+ /* Get a descriptor */
+ Descriptor =3D ArmAllocateMemoryDescriptor();
+ if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES;
+ =
+ /* Check if we are using another descriptor */
+ if (UseNext)
+ {
+ /* Allocate that one too */
+ NextDescriptor =3D ArmAllocateMemoryDescriptor();
+ if (!NextDescriptor) return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ =
+ /* Build the descriptor we got */
+ Descriptor->MemoryType =3D MemoryType;
+ Descriptor->BasePage =3D BasePage;
+ Descriptor->PageCount =3D PageCount;
+ =
+ /* Check if we're starting at the same place as the old one */
+ if (BasePage =3D=3D MemoryDescriptor->BasePage)
+ {
+ /* Simply decrease the old descriptor and rebase it */
+ MemoryDescriptor->BasePage +=3D PageCount;
+ MemoryDescriptor->PageCount -=3D PageCount;
+ MemoryDescriptor->MemoryType =3D CurrentType;
+ }
+ else if (Delta + PageCount =3D=3D MemoryDescriptor->PageCount)
+ {
+ /* We finish where the old one did, shorten it */
+ MemoryDescriptor->PageCount -=3D PageCount;
+ MemoryDescriptor->MemoryType =3D CurrentType;
+ }
+ else
+ {
+ /* We're inside the current block, mark our free region */
+ NextDescriptor->MemoryType =3D LoaderFree;
+ NextDescriptor->BasePage =3D BasePage + PageCount;
+ NextDescriptor->PageCount =3D MemoryDescriptor->PageCount -
+ (PageCount + Delta);
+ =
+ /* And cut down the current descriptor */
+ MemoryDescriptor->PageCount =3D Delta;
+ MemoryDescriptor->MemoryType =3D CurrentType;
+ =
+ /* Finally, insert our new free descriptor into the list */
+ ArmInsertMemoryDescriptor(NextDescriptor);
+ }
+ =
+ /* Insert the descriptor we allocated */
+ ArmInsertMemoryDescriptor(Descriptor);
+ }
+ =
+ /* Return success */
+ return STATUS_SUCCESS;
+}
+
+PMEMORY_ALLOCATION_DESCRIPTOR
+NTAPI
+ArmFindMemoryDescriptor(IN ULONG BasePage)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock =3D NULL;
+ PLIST_ENTRY NextEntry, ListHead;
+ =
+ /* Scan the memory descriptor list */
+ ListHead =3D &ArmLoaderBlock->MemoryDescriptorListHead;
+ NextEntry =3D ListHead->Flink;
+ while (NextEntry !=3D ListHead)
+ {
+ /* Get the current descriptor */
+ MdBlock =3D CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ /* Check if it can contain our memory range */
+ if ((MdBlock->BasePage <=3D BasePage) &&
+ (MdBlock->BasePage + MdBlock->PageCount > BasePage))
+ {
+ /* It can, break out */
+ break;
+ }
+ =
+ /* Go to the next descriptor */
+ NextEntry =3D NextEntry->Flink;
+ }
+ =
+ /* Return the descriptor we found, if any */
+ return MdBlock;
+}
+
+NTSTATUS
+NTAPI
+ArmCreateMemoryDescriptor(IN TYPE_OF_MEMORY MemoryType,
+ IN ULONG BasePage,
+ IN ULONG PageCount,
+ IN ULONG Alignment,
+ OUT PULONG ReturnedBase)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+ ULONG AlignedBase, AlignedLimit;
+ PMEMORY_ALLOCATION_DESCRIPTOR ActiveMdBlock;
+ ULONG ActiveAlignedBase =3D 0;
+ PLIST_ENTRY NextEntry, ListHead;
+ =
+ /* If no information was given, make some assumptions */
+ if (!Alignment) Alignment =3D 1;
+ if (!PageCount) PageCount =3D 1;
+ =
+ /* Start looking for a matching descvriptor */
+ do
+ {
+ /* Calculate the limit of the range */
+ AlignedLimit =3D PageCount + BasePage;
+ =
+ /* Find a descriptor that already contains our base address */
+ MdBlock =3D ArmFindMemoryDescriptor(BasePage);
+ if (MdBlock)
+ {
+ /* If it contains our limit as well, break out early */
+ if ((MdBlock->PageCount + MdBlock->BasePage) >=3D AlignedLimit=
) break;
+ }
+ =
+ /* Loop the memory list */
+ AlignedBase =3D 0;
+ ActiveMdBlock =3D NULL;
+ ListHead =3D &ArmLoaderBlock->MemoryDescriptorListHead;
+ NextEntry =3D ListHead->Flink;
+ while (NextEntry !=3D ListHead)
+ {
+ /* Get the current descriptors */
+ MdBlock =3D CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+ =
+ /* Align the base address and our limit */
+ AlignedBase =3D (MdBlock->BasePage + (Alignment - 1)) &~ Align=
ment;
+ AlignedLimit =3D MdBlock->PageCount -
+ AlignedBase +
+ MdBlock->BasePage;
+ =
+ /* Check if this is a free block that can satisfy us */
+ if ((MdBlock->MemoryType =3D=3D LoaderFree) &&
+ (AlignedLimit <=3D MdBlock->PageCount) &&
+ (PageCount <=3D AlignedLimit))
+ {
+ /* It is, stop searching */
+ ActiveMdBlock =3D MdBlock;
+ ActiveAlignedBase =3D AlignedBase;
+ break;
+ }
+ =
+ /* Try the next block */
+ NextEntry =3D NextEntry->Flink;
+ }
+ =
+ /* See if we came up with an adequate block */
+ if (ActiveMdBlock)
+ {
+ /* Generate a descriptor in it */
+ *ReturnedBase =3D AlignedBase;
+ return ArmBuildMemoryDescriptor(ActiveMdBlock,
+ MemoryType,
+ ActiveAlignedBase,
+ PageCount);
+ }
+ } while (TRUE);
+ =
+ /* We found a matching block, generate a descriptor with it */
+ *ReturnedBase =3D BasePage;
+ return ArmBuildMemoryDescriptor(MdBlock, MemoryType, BasePage, PageCou=
nt);
+}
+
+NTSTATUS
+NTAPI
+ArmBuildLoaderMemoryList(VOID)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ MEMORY_DESCRIPTOR *Memory;
+ ULONG i;
+ =
+ /* Loop all BIOS Memory Descriptors */
+ for (i =3D 0; i < NumberDescriptors; i++)
+ {
+ /* Get the current descriptor */
+ Memory =3D &MDArray[i];
+ =
+ /* Allocate an NT Memory Descriptor */
+ Descriptor =3D ArmAllocateMemoryDescriptor();
+ if (!Descriptor) return ENOMEM;
+ =
+ /* Copy the memory type */
+ Descriptor->MemoryType =3D Memory->MemoryType;
+ if (Memory->MemoryType =3D=3D MemoryFreeContiguous)
+ {
+ /* Convert this to free */
+ Descriptor->MemoryType =3D LoaderFree;
+ }
+ else if (Memory->MemoryType =3D=3D MemorySpecialMemory)
+ {
+ /* Convert this to special memory */
+ Descriptor->MemoryType =3D LoaderSpecialMemory;
+ }
+ =
+ /* Copy the range data */
+ Descriptor->BasePage =3D Memory->BasePage;
+ Descriptor->PageCount =3D Memory->PageCount;
+ =
+ /* Insert the descriptor */
+ if (Descriptor->PageCount) ArmInsertMemoryDescriptor(Descriptor);
+ }
+ =
+ /* All went well */
+ return STATUS_SUCCESS;
+}
=
VOID
ArmSetupPageDirectory(VOID)
@@ -70,20 +695,23 @@
ARM_DOMAIN_REGISTER DomainRegister;
ARM_PTE Pte;
ULONG i, j;
- PARM_TRANSLATION_TABLE MasterTable;
- PARM_COARSE_PAGE_TABLE BootTable, KernelTable;
+ PARM_TRANSLATION_TABLE ArmTable;
+ PARM_COARSE_PAGE_TABLE BootTable, KernelTable, FlatMapTable, MasterTab=
le, HyperSpaceTable;
=
//
// Get the PDEs that we will use
//
- MasterTable =3D &ArmTranslationTable;
+ ArmTable =3D &ArmTranslationTable;
BootTable =3D &BootTranslationTable;
KernelTable =3D &KernelTranslationTable;
+ FlatMapTable =3D &FlatMapTranslationTable;
+ MasterTable =3D &MasterTranslationTable;
+ HyperSpaceTable =3D &HyperSpaceTranslationTable;
=
//
// Set the master L1 PDE as the TTB
//
- TtbRegister.AsUlong =3D (ULONG)MasterTable;
+ TtbRegister.AsUlong =3D (ULONG)ArmTable;
ASSERT(TtbRegister.Reserved =3D=3D 0);
KeArmTranslationTableRegisterSet(TtbRegister);
=
@@ -97,7 +725,7 @@
//
// Set Fault PTEs everywhere
//
- RtlZeroMemory(MasterTable, sizeof(ARM_TRANSLATION_TABLE));
+ RtlZeroMemory(ArmTable, sizeof(ARM_TRANSLATION_TABLE));
=
//
// Identity map the first MB of memory
@@ -110,22 +738,102 @@
Pte.L1.Section.Access =3D SupervisorAccess;
Pte.L1.Section.BaseAddress =3D 0;
Pte.L1.Section.Ignored =3D Pte.L1.Section.Ignored1 =3D 0;
- MasterTable->Pte[0] =3D Pte;
-
+ ArmTable->Pte[0] =3D Pte;
+ =
//
// Map the page in MMIO space that contains the serial port into virtu=
al memory
//
Pte.L1.Section.BaseAddress =3D ArmBoardBlock->UartRegisterBase >> PDE_=
SHIFT;
- MasterTable->Pte[UART_VIRTUAL >> PDE_SHIFT] =3D Pte;
-
- //
- // Create template PTE for the coarse page tables which map the first =
8MB
+ ArmTable->Pte[UART_VIRTUAL >> PDE_SHIFT] =3D Pte;
+
+ //
+ // Create template PTE for the coarse page table which maps the PTE_BA=
SE
//
Pte.L1.Coarse.Type =3D CoarsePte;
Pte.L1.Coarse.Domain =3D Domain0;
Pte.L1.Coarse.Reserved =3D 1; // ARM926EJ-S manual recommends setting =
to 1
+ Pte.L1.Coarse.Ignored =3D Pte.L1.Coarse.Ignored1 =3D 0;
+ Pte.L1.Coarse.BaseAddress =3D (ULONG)FlatMapTable >
CPT_SHIFT;
+
+ //
+ // On x86, there is 4MB of space, starting at 0xC0000000 to 0xC0400000
+ // which contains the mappings for each PTE on the system. 4MB is need=
ed
+ // since for 4GB, there will be 1 million PTEs, each of 4KB.
+ //
+ // To describe a 4MB region, on x86, only requires a page table, which=
can
+ // be linked from the page table directory.
+ //
+ // On the other hand, on ARM, we can only describe 1MB regions, so we =
need
+ // four times less PTE entries to represent a single mapping (an L2 co=
arse
+ // page table). This is problematic, because this would only take up 1=
KB of
+ // space, and we can't have a page that small.
+ //
+ // This means we must:
+ //
+ // - Allocate page tables (in physical memory) with 4KB granularity, i=
nstead
+ // of 1KB (the other 3KB is unused and invalid).
+ //
+ // - "Skip" the other 3KB in the region, because we can't point to
ano=
ther
+ // coarse page table after just 1KB.
+ //
+ // So 0xC0000000 will be mapped to the page table that maps the range =
of
+ // 0x00000000 to 0x01000000, while 0xC0001000 till be mapped to the pa=
ge
+ // table that maps the area from 0x01000000 to 0x02000000, and so on. =
In
+ // total, this will require 4 million entries, and additionally, becau=
se of
+ // the padding, since each 256 entries will be 4KB (instead of 1KB), t=
his
+ // means we'll need 16MB (0xC0000000 to 0xC1000000).
+ //
+ // We call this region the flat-map area
+ //
+ for (i =3D (PTE_BASE >> PDE_SHIFT); i < ((PTE_BASE + 0x1000000) >>
PDE=
_SHIFT); i++)
+ {
+ //
+ // Write PTE and update the base address (next MB) for the next one
+ //
+ ArmTable->Pte[i] =3D Pte;
+ Pte.L1.Coarse.BaseAddress +=3D 4;
+ }
+ =
+ //
+ // On x86, there is also the region of 0xC0300000 to 0xC03080000 which=
maps
+ // to the various PDEs on the system. Yes, this overlaps with the abov=
e, and
+ // works because of an insidious dark magic (self-mapping the PDE as a=
PTE).
+ // Unfortunately, this doesn't work on ARM, firstly because the size o=
f a L1
+ // page table is different than from an L2 page table, and secondly, w=
hich
+ // is even worse, the format for an L1 page table is different than th=
e one
+ // for an L2 page table -- basically meaning we cannot self-map.
+ //
+ // However, we somewhat emulate this behavior on ARM. This will be exp=
ensive
+ // since we manually need to keep track of every page directory added =
and
+ // add an entry in our flat-map region. We also need to keep track of =
every
+ // change in the TTB, so that we can update the mappings in our PDE re=
gion.
+ //
+ // Note that for us, this region starts at 0xC1000000, after the flat-=
map
+ // area.
+ //
+ // Finally, to deal with different sizes (1KB page tables, 4KB page si=
ze!),
+ // we pad the ARM L2 page tables to make them 4KB, so that each page w=
ill
+ // therefore point to an L2 page table.
+ //
+ // This region is a lot easier than the first -- an L1 page table is o=
nly
+ // 16KB, so to access any index inside it, we just need 4 pages, since=
each
+ // page is 4KB... Clearly, there's also no need to pad in this case.
+ //
+ // We'll call this region the master translation area.
+ //
+ Pte.L1.Coarse.BaseAddress =3D (ULONG)MasterTable >
CPT_SHIFT;
+ ArmTable->Pte[PDE_BASE >> PDE_SHIFT] =3D Pte;
+ =
+ //
+ // Now create the template for the hyperspace table which maps 1MB
+ //
+ Pte.L1.Coarse.BaseAddress =3D (ULONG)HyperSpaceTable >
CPT_SHIFT;
+ ArmTable->Pte[HYPER_SPACE
>> PDE_SHIFT] =3D Pte;
+
+ //
+ // Now create the template for the coarse page tables which map the fi=
rst 8MB
+ //
Pte.L1.Coarse.BaseAddress =3D (ULONG)BootTable >
CPT_SHIFT;
- Pte.L1.Coarse.Ignored =3D Pte.L1.Coarse.Ignored1 =3D 0;
=
//
// Map 0x00000000 - 0x007FFFFF to 0x80000000 - 0x807FFFFF.
@@ -136,8 +844,8 @@
//
// Write PTE and update the base address (next MB) for the next one
//
- MasterTable->Pte[i] =3D Pte;
- Pte.L1.Coarse.BaseAddress++;
+ ArmTable->Pte[i] =3D Pte;
+ Pte.L1.Coarse.BaseAddress +=3D 4;
}
=
//
@@ -156,8 +864,8 @@
//
// Write PTE and update the base address (next MB) for the next one
//
- MasterTable->Pte[i] =3D Pte;
- Pte.L1.Coarse.BaseAddress++;
+ ArmTable->Pte[i] =3D Pte;
+ Pte.L1.Coarse.BaseAddress +=3D 4;
}
=
//
@@ -225,6 +933,88 @@
//
KernelTable++;
}
+
+ //
+ // Now we need to create the PTEs for the addresses which have been ma=
pped
+ // already.
+ //
+ // We have allocated 4 page table directories:
+ //
+ // - One for the kernel, 6MB
+ // - One for low-memory FreeLDR, 8MB
+ // - One for identity-mapping below 1MB, 1MB
+ // - And finally, one for the flat-map itself, 16MB
+ // =
+ // - Each MB mapped is a 1KB table, which we'll use a page to referenc=
e, so
+ // we will require 31 pages.
+ //
+ =
+ //
+ // For the 0x80000000 region (8MB)
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&BootTranslationTable >> PTE_SHIFT;
+ FlatMapTable =3D &(&FlatMapTranslationTable)[0x80000000 >> 28];
+ for (i =3D 0; i < 8; i++)
+ {
+ //
+ // Point to the page table mapping the next MB
+ //
+ FlatMapTable->Pte[i] =3D Pte;
+ Pte.L2.Small.BaseAddress++; =
+ }
+ =
+ //
+ // For the 0x80800000 region (6MB)
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&KernelTranslationTable >> PTE_SHI=
FT;
+ for (i =3D 8; i < 14; i++)
+ {
+ //
+ // Point to the page table mapping the next MB
+ //
+ FlatMapTable->Pte[i] =3D Pte;
+ Pte.L2.Small.BaseAddress++; =
+ }
+ =
+ //
+ // For the 0xC0000000 region (16MB)
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&FlatMapTranslationTable >> PTE_SH=
IFT;
+ FlatMapTable =3D &(&FlatMapTranslationTable)[0xC0000000 >> 28];
+ for (i =3D 0; i < 16; i++)
+ {
+ //
+ // Point to the page table mapping the next MB
+ //
+ FlatMapTable->Pte[i] =3D Pte;
+ Pte.L2.Small.BaseAddress++; =
+ }
+ =
+ //
+ // For the 0xC1000000 region (1MB)
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&MasterTranslationTable >> PTE_SHI=
FT;
+ FlatMapTable->Pte[16] =3D Pte;
+ =
+ //
+ // And finally for the 0xC1100000 region (1MB)
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&HyperSpaceTranslationTable >> PTE=
_SHIFT;
+ FlatMapTable->Pte[17] =3D Pte;
+
+ //
+ // Now we handle the master translation area for our PDEs. We'll just =
make
+ // the 4 page tables point to the ARM TTB.
+ //
+ Pte.L2.Small.BaseAddress =3D (ULONG)&ArmTranslationTable >> PTE_SHIFT;
+ for (i =3D 0; i < 4; i++)
+ {
+ //
+ // Point to the page table mapping the next MB
+ //
+ MasterTable->Pte[i] =3D Pte;
+ Pte.L2.Small.BaseAddress++; =
+ }
}
=
VOID
@@ -259,17 +1049,25 @@
ArmPrepareForReactOS(IN BOOLEAN Setup)
{ =
ARM_CACHE_REGISTER CacheReg;
- PVOID Base;
+ PVOID Base, MemBase;
PCHAR BootPath, HalPath;
+ NTSTATUS Status;
+ ULONG Dummy, i;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ =
+ //
+ // Allocate the ARM Shared Heap
+ //
+ ArmSharedHeap =3D MmAllocateMemory(PAGE_SIZE);
+ ArmSharedHeapSize =3D 0;
+ if (!ArmSharedHeap) return;
=
//
// Allocate the loader block and extension
//
- ArmLoaderBlock =3D MmAllocateMemoryWithType(sizeof(LOADER_PARAMETER_BL=
OCK),
- LoaderOsloaderHeap);
+ ArmLoaderBlock =3D ArmAllocateFromSharedHeap(sizeof(LOADER_PARAMETER_B=
LOCK));
if (!ArmLoaderBlock) return;
- ArmExtension =3D MmAllocateMemoryWithType(sizeof(LOADER_PARAMETER_EXTE=
NSION),
- LoaderOsloaderHeap);
+ ArmExtension =3D ArmAllocateFromSharedHeap(sizeof(LOADER_PARAMETER_EXT=
ENSION));
if (!ArmExtension) return;
=
//
@@ -286,8 +1084,78 @@
ArmLoaderBlock->SetupLdrBlock =3D NULL;
=
//
- // TODO: Setup memory descriptors
- //
+ // Add the Board Memory Map from U-Boot into the STARTUP.COM-style =
+ // BIOS descriptor format -- this needs to be removed later.
+ //
+ ArmBuildBoardMemoryMap();
+ =
+ //
+ // Now basically convert these entries to the ARC format, so that we c=
an
+ // get a good map of free (usable) memory
+ //
+ ArmBuildOsMemoryMap();
+
+ //
+ // NT uses an extended ARC format, with slightly different memory type=
s.
+ // We also want to link the ARC descriptors together into a linked lis=
t,
+ // instead of the array, and allocate the semi-permanent storage in wh=
ich
+ // these entries will be stored so that the kernel can read them.
+ //
+ ArmBuildLoaderMemoryList();
+ =
+ //
+ // Setup descriptor for the shared heap
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderOsloaderHeap,
+ (ULONG_PTR)ArmSharedHeap >> PAGE_SH=
IFT,
+ ADDRESS_AND_SIZE_TO_SPAN_PAGES(ArmS=
haredHeap,
+ ArmS=
haredHeapSize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
+ //
+ // Setup descriptor for the boot stack
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderOsloaderStack,
+ (ULONG_PTR)&BootStack >
PAGE_SHIFT,
+
4,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
+ //
+ // Setup descriptor for the boot page tables
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderMemoryData,
+ (ULONG_PTR)&TranslationTableStart >=
PAGE_SHIFT,
+
((ULONG_PTR)&TranslationTableEnd -
+ (ULONG_PTR)&TranslationTableStart)=
/ PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
+ //
+ // Setup descriptor for the kernel
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderSystemCode,
+ KernelData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(Kern=
elData,
+ Kern=
elSize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
+ // Setup descriptor for the HAL
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderHalCode,
+ HalData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(HalD=
ata,
+ HalS=
ize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
=
//
// Setup registry data
@@ -295,14 +1163,24 @@
ArmLoaderBlock->RegistryBase =3D (PVOID)((ULONG_PTR)RegistryData | KSE=
G0_BASE);
=
//
+ // Create an MD for it
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderRegistryData,
+ RegistryData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(Regi=
stryData,
+ Regi=
strySize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
// TODO: Setup ARC Hardware tree data
//
=
//
// Setup NLS data
//
- ArmNlsDataBlock =3D MmAllocateMemoryWithType(sizeof(NLS_DATA_BLOCK),
- LoaderOsloaderHeap);
+ ArmNlsDataBlock =3D ArmAllocateFromSharedHeap(sizeof(NLS_DATA_BLOCK));
ArmLoaderBlock->NlsData =3D ArmNlsDataBlock;
ArmLoaderBlock->NlsData->AnsiCodePageData =3D (PVOID)(AnsiData | KSEG0=
_BASE);
ArmLoaderBlock->NlsData->OemCodePageData =3D (PVOID)(OemData | KSEG0_B=
ASE);
@@ -310,8 +1188,70 @@
ArmLoaderBlock->NlsData =3D (PVOID)((ULONG_PTR)ArmLoaderBlock->NlsData=
| KSEG0_BASE);
=
//
+ // Setup ANSI NLS Memory Descriptor
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderNlsData,
+ AnsiData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(Ansi=
Data,
+ Ansi=
Size),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
+ // Setup OEM NLS Memory Descriptor
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderNlsData,
+ OemData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(OemD=
ata,
+ OemS=
ize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
+ // Setup Unicode NLS Memory Descriptor
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderNlsData,
+ UnicodeData >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(Unic=
odeData,
+ Unic=
odeSize),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
+ // Setup loader entry for the kernel
+ //
+ LdrEntry =3D ArmAllocateFromSharedHeap(sizeof(LDR_DATA_TABLE_ENTRY));
+ RtlZeroMemory(LdrEntry, sizeof(LDR_DATA_TABLE_ENTRY));
+ LdrEntry->DllBase =3D (PVOID)KernelBase;
+ LdrEntry->SizeOfImage =3D KernelSize;
+ LdrEntry->EntryPoint =3D KernelEntryPoint;
+ LdrEntry->LoadCount =3D 1;
+ LdrEntry->Flags =3D LDRP_IMAGE_DLL | LDRP_ENTRY_PROCESSED;
+ InsertTailList(&ArmLoaderBlock->LoadOrderListHead,
&LdrEntry->InLoadOr=
derLinks);
+ =
+ //
// TODO: Setup boot-driver data
//
+ =
+ //
+ // Build descriptors for the drivers loaded
+ //
+ for (i =3D 0; i < Drivers; i++)
+ {
+ //
+ // Build a descriptor for the driver
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderBootDriver,
+ DriverData[i] >
PAGE_SHIFT,
+
ADDRESS_AND_SIZE_TO_SPAN_PAGES(=
DriverData[i],
+ =
DriverSize[i]),
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ }
=
//
// Setup extension parameters
@@ -377,7 +1317,7 @@
ArmLoaderBlock->u.Arm.SecondLevelDcacheFillSize =3D
ArmLoaderBlock->u.Arm.SecondLevelIcacheSize =3D
ArmLoaderBlock->u.Arm.SecondLevelIcacheFillSize =3D 0;
-
+ =
//
// Allocate the Interrupt stack
//
@@ -386,6 +1326,16 @@
ArmLoaderBlock->u.Arm.InterruptStack +=3D KERNEL_STACK_SIZE;
=
//
+ // Build an entry for it
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderStartupDpcStack,
+ (ULONG_PTR)Base >
PAGE_SHIFT,
+
KERNEL_STACK_SIZE / PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
// Allocate the Kernel Boot stack
//
Base =3D MmAllocateMemoryWithType(KERNEL_STACK_SIZE, LoaderStartupKern=
elStack);
@@ -393,26 +1343,68 @@
ArmLoaderBlock->KernelStack +=3D KERNEL_STACK_SIZE;
=
//
+ // Build an entry for it
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderStartupKernelStack,
+ (ULONG_PTR)Base >
PAGE_SHIFT,
+
KERNEL_STACK_SIZE / PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
+ //
// Allocate the Abort stack
//
Base =3D MmAllocateMemoryWithType(KERNEL_STACK_SIZE, LoaderStartupPani=
cStack);
ArmLoaderBlock->u.Arm.PanicStack =3D KSEG0_BASE | (ULONG)Base;
ArmLoaderBlock->u.Arm.PanicStack +=3D KERNEL_STACK_SIZE;
-
- //
- // Allocate the PCR page -- align it to 1MB (we only need 4KB)
+ =
+ //
+ // Build an entry for it
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderStartupPanicStack,
+ (ULONG_PTR)Base >
PAGE_SHIFT,
+
KERNEL_STACK_SIZE / PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
+ //
+ // Allocate the PCR/KUSER_SHARED page -- align it to 1MB (we only need=
2x4KB)
//
Base =3D MmAllocateMemoryWithType(2 * 1024 * 1024, LoaderStartupPcrPag=
e);
+ MemBase =3D Base;
Base =3D (PVOID)ROUND_UP(Base, 1 * 1024 * 1024);
ArmLoaderBlock->u.Arm.PcrPage =3D (ULONG)Base >> PDE_SHIFT;
-
- //
- // Allocate PDR pages -- align them to 1MB (we only need 3xKB)
+ =
+ //
+ // Build an entry for the KPCR and KUSER_SHARED_DATA
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderStartupPcrPage,
+ (ULONG_PTR)MemBase >
PAGE_SHIFT,
+
(2 * 1024 * 1024) / PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+ =
+ //
+ // Allocate PDR pages -- align them to 1MB (we only need 3x4KB)
//
Base =3D MmAllocateMemoryWithType(4 * 1024 * 1024, LoaderStartupPdrPag=
e);
+ MemBase =3D Base;
Base =3D (PVOID)ROUND_UP(Base, 1 * 1024 * 1024);
ArmLoaderBlock->u.Arm.PdrPage =3D (ULONG)Base >> PDE_SHIFT;
- =
+
+ //
+ // Build an entry for the PDR, PRCB and initial KPROCESS/KTHREAD
+ //
+ Status =3D ArmCreateMemoryDescriptor(LoaderStartupPdrPage,
+ (ULONG_PTR)MemBase >
PAGE_SHIFT,
+
(4 * 1024 * 1024) / PAGE_SIZE,
+ 0,
+ &Dummy);
+ if (Status !=3D STATUS_SUCCESS) return;
+
//
// Set initial PRCB, Thread and Process on the last PDR page
//
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/=
arch/arm/macharm.c?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c Mon Mar 10 12:27:=
14 2008
@@ -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
//
@@ -37,6 +41,22 @@
//
ASSERT((ArmBoardBlock->BoardType =3D=3D MACH_TYPE_FEROCEON) ||
(ArmBoardBlock->BoardType =3D=3D MACH_TYPE_VERSATILE_PB));
+
+ //
+ // Save data required for memory initialization
+ //
+ ArmBoardMemoryMapRangeCount =3D ArmBoardBlock->MemoryMapEntryCount;
+ ASSERT(ArmBoardMemoryMapRangeCount !=3D 0);
+ ASSERT(ArmBoardMemoryMapRangeCount < 16);
+ for (i =3D 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
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/=
reactos/imageldr.c?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c Mon Mar 10 12:27:=
14 2008
@@ -16,7 +16,10 @@
);
=
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
-PVOID AnsiData, OemData, UnicodeData, RegistryData;
+ULONG Drivers;
+PVOID AnsiData, OemData, UnicodeData, RegistryData, KernelData, HalData, D=
riverData[16];
+ULONG RegistrySize, AnsiSize, OemSize, UnicodeSize, KernelSize, HalSize, D=
riverSize[16];
+
/* MODULE MANAGEMENT *****************************************************=
*****/
=
PLOADER_MODULE
@@ -101,19 +104,23 @@
if (!_stricmp(NameBuffer, "ansi.nls"))
{
AnsiData =3D (PVOID)NextModuleBase;
+ AnsiSize =3D LocalModuleSize;
}
else if (!_stricmp(NameBuffer, "oem.nls"))
{
OemData =3D (PVOID)NextModuleBase;
+ OemSize =3D LocalModuleSize;
}
else if (!_stricmp(NameBuffer, "casemap.nls"))
{
UnicodeData =3D (PVOID)NextModuleBase;
+ UnicodeSize =3D LocalModuleSize;
}
else if (!(_stricmp(NameBuffer, "system")) ||
!(_stricmp(NameBuffer, "system.hiv")))
{
RegistryData =3D (PVOID)NextModuleBase;
+ RegistrySize =3D LocalModuleSize;
}
=
/* Load the file image */
@@ -548,6 +555,24 @@
reactos_modules[ImageId].String =3D (ULONG_PTR)reactos_module_strings[=
ImageId];
LoaderBlock.ModsCount++;
=
+ /* Detect kernel or HAL */
+ if (!_stricmp(Name, "ntoskrnl.exe"))
+ {
+ KernelData =3D (PVOID)NextModuleBase;
+ KernelSize =3D ImageSize;
+ }
+ else if (!_stricmp(Name, "hal.dll"))
+ {
+ HalData =3D (PVOID)NextModuleBase;
+ HalSize =3D ImageSize;
+ }
+ else
+ {
+ DriverData[Drivers] =3D (PVOID)NextModuleBase;
+ DriverSize[Drivers] =3D ImageSize;
+ Drivers++;
+ }
+ =
/* Increase the next Load Base */
NextModuleBase =3D ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
=
Modified: trunk/reactos/include/ndk/arm/mmtypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/arm/mmtyp=
es.h?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/include/ndk/arm/mmtypes.h (original)
+++ trunk/reactos/include/ndk/arm/mmtypes.h Mon Mar 10 12:27:14 2008
@@ -47,19 +47,87 @@
//
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_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;
=
//
Modified: trunk/reactos/ntoskrnl/include/internal/arm/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/inte=
rnal/arm/ke.h?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/include/internal/arm/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/ke.h Mon Mar 10 12:27:14 20=
08
@@ -174,5 +174,6 @@
);
=
#define KeArchInitThreadWithContext KeArmInitThreadWithContext
+#define KiSystemStartupReal KiSystemStartup
=
#endif
Modified: trunk/reactos/ntoskrnl/include/internal/arm/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/inte=
rnal/arm/mm.h?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/include/internal/arm/mm.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/mm.h Mon Mar 10 12:27:14 20=
08
@@ -113,6 +113,7 @@
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
Modified: trunk/reactos/ntoskrnl/ke/arm/arm_kprintf.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/arm_k=
printf.c?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/ke/arm/arm_kprintf.c (original)
+++ trunk/reactos/ntoskrnl/ke/arm/arm_kprintf.c Mon Mar 10 12:27:14 2008
@@ -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)
Modified: trunk/reactos/ntoskrnl/ke/freeldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/freeldr.c=
?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/ke/freeldr.c (original)
+++ trunk/reactos/ntoskrnl/ke/freeldr.c Mon Mar 10 12:27:14 2008
@@ -771,7 +771,7 @@
if (MdBlock)
{
/* If it contains our limit as well, break out early */
- if ((MdBlock->PageCount + MdBlock->BasePage) > AlignedLimit) b=
reak;
+ if ((MdBlock->PageCount + MdBlock->BasePage) >=3D AlignedLimit=
) break;
}
=
/* Loop the memory list */
Modified: trunk/reactos/ntoskrnl/mm/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/arm/stubs=
.c?rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/mm/arm/stubs.c (original)
+++ trunk/reactos/ntoskrnl/mm/arm/stubs.c Mon Mar 10 12:27:14 2008
@@ -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 @@
MmGetPageDirectory(VOID)
{
//
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
+ // Return the TTB
+ //
+ return (PULONG)KeArmTranslationTableRegisterGet().AsUlong;
}
=
=
@@ -96,10 +118,65 @@
MmDeletePageTable(IN PEPROCESS Process,
IN PVOID Address)
{
- //
- // TODO
- //
- UNIMPLEMENTED;
+ PMMPTE PointerPde;
+ =
+ //
+ // Not valid for kernel addresses
+ //
+ DPRINT1("MmDeletePageTable(%p, %p)\n", Process, Address);
+ ASSERT(Address < MmSystemRangeStart);
+ =
+ //
+ // Check if this is for a different process
+ //
+ if ((Process) && (Process !=3D PsGetCurrentProcess()))
+ {
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ return;
+ }
+ =
+ //
+ // Get the PDE
+ //
+ PointerPde =3D MiGetPdeAddress(Address);
+
+ //
+ // On ARM, we use a section mapping for the original low-memory mapping
+ //
+ if ((Address) || (PointerPde->u.Hard.L1.Section.Type !=3D SectionPte))
+ {
+ //
+ // Make sure it's valid
+ //
+ ASSERT(PointerPde->u.Hard.L1.Coarse.Type =3D=3D CoarsePte);
+ }
+ =
+ //
+ // Clear the PDE
+ //
+ PointerPde->u.Hard.AsUlong =3D 0;
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type =3D=3D FaultPte);
+ =
+ //
+ // Check if this is a kernel PDE
+ //
+ if ((PointerPde >=3D (PMMPTE)PTE_BASE) && (PointerPde <
(PMMPTE)PTE_BA=
SE + (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 @@
MmIsPagePresent(IN PEPROCESS Process,
IN PVOID Address)
{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
+ PMMPTE Pte;
+ =
+ //
+ // Check if this is for a different process
+ //
+ if ((Process) && (Process !=3D PsGetCurrentProcess()))
+ {
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ return 0;
+ }
+
+ //
+ // Get the PDE
+ //
+ Pte =3D MiGetPdeAddress(Address);
+ if (Pte->u.Hard.L1.Fault.Type !=3D FaultPte)
+ {
+ //
+ // Get the PTE
+ //
+ Pte =3D MiGetPteAddress(Address);
+ }
+ =
+ //
+ // Return whether or not it's valid
+ //
+ return (Pte->u.Hard.L1.Fault.Type !=3D FaultPte);
+ =
+ =
}
=
BOOLEAN
@@ -237,15 +341,107 @@
NTSTATUS
NTAPI
MmCreateVirtualMappingForKernel(IN PVOID Address,
- IN ULONG flProtect,
- IN PPFN_TYPE Pages,
+ IN ULONG Protection,
+ IN PPFN_NUMBER Pages,
IN ULONG PageCount)
{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
+ 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 >=3D MmSystemRangeStart);
+
+ //
+ // Get our templates
+ //
+ TempPte =3D MiArmTemplatePte;
+ TempPde =3D MiArmTemplatePde;
+
+ //
+ // Check if we have PDEs for this region
+ //
+ PointerPde =3D MiGetPdeAddress(Address);
+ LastPde =3D PointerPde + (PageCount / 256);
+ while (PointerPde <=3D LastPde)
+ {
+ //
+ // Check if we need to allocate the PDE
+ //
+ if (PointerPde->u.Hard.L1.Fault.Type =3D=3D FaultPte)
+ {
+ //
+ // Request a page
+ //
+ Status =3D MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ if (!NT_SUCCESS(Status)) return Status;
+ =
+ //
+ // Setup the PFN
+ //
+ TempPde.u.Hard.L1.Coarse.BaseAddress =3D (Pfn << PAGE_SHIFT) >=
CPT_SHIFT;
+ =
+ //
+ // Write the PDE
+ //
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type =3D=3D FaultPte);
+ ASSERT(TempPde.u.Hard.L1.Coarse.Type =3D=3D CoarsePte);
+ *PointerPde =3D TempPde;
+ =
+ //
+ // Get the PTE for this 1MB region
+ //
+ PointerPte =3D MiGetPteAddress(MiGetPteAddress(Address));
+ =
+ //
+ // Write the PFN of the PDE
+ //
+ TempPte.u.Hard.L2.Small.BaseAddress =3D Pfn;
+
+ //
+ // Write the PTE
+ //
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type =3D=3D FaultPte);
+ ASSERT(TempPte.u.Hard.L2.Small.Type =3D=3D SmallPte);
+ *PointerPte =3D TempPte;
+ }
+ =
+ //
+ // Next
+ //
+ PointerPde++;
+ }
+ =
+ //
+ // Get start and end address and loop each PTE
+ //
+ PointerPte =3D MiGetPteAddress(Address);
+ LastPte =3D PointerPte + PageCount - 1;
+ while (PointerPte <=3D LastPte)
+ {
+ //
+ // Set the PFN
+ //
+ TempPte.u.Hard.L2.Small.BaseAddress =3D *Pages++;
+ =
+ //
+ // Write the PTE
+ //
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type =3D=3D FaultPte);
+ ASSERT(TempPte.u.Hard.L2.Small.Type =3D=3D SmallPte);
+ *PointerPte =3D TempPte;
+ =
+ //
+ // Next
+ //
+ PointerPte++;
+ }
+ =
+ //
+ // All done
+ //
+ return STATUS_SUCCESS;
}
=
NTSTATUS
@@ -265,10 +461,27 @@
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 @@
NTAPI
MmCreateVirtualMapping(IN PEPROCESS Process,
IN PVOID Address,
- IN ULONG flProtect,
+ IN ULONG Protection,
IN PPFN_TYPE Pages,
IN ULONG PageCount)
{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
+ ULONG i;
+ DPRINT1("MmCreateVirtualMapping(%p %x, %x, %x, %d)\n",
+ Process, Address, Protection, *Pages, PageCount);
+ =
+ //
+ // Loop each page
+ //
+ for (i =3D 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 @@
NTAPI
MmSetPageProtect(IN PEPROCESS Process,
IN PVOID Address,
- IN ULONG flProtect)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
+ IN ULONG Protection)
+{
+ //
+ // We don't enforce any protection on the pages -- they are all RWX
+ //
+ return;
}
=
/*
@@ -335,6 +566,130 @@
NTAPI
MmCreateHyperspaceMapping(IN PFN_TYPE Page)
{
+ PMMPTE PointerPte, FirstPte, LastPte;
+ MMPTE TempPte;
+ PVOID Address;
+ DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Page);
+
+ //
+ // Loop hyperspace PTEs (1MB)
+ //
+ FirstPte =3D PointerPte =3D MiGetPteAddress(HYPER_SPACE);
+ LastPte =3D PointerPte + 256;
+ while (PointerPte <=3D LastPte)
+ {
+ //
+ // Find a free slot
+ //
+ if (PointerPte->u.Hard.L2.Fault.Type =3D=3D 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 =3D MiArmTemplatePte;
+ TempPte.u.Hard.L2.Small.BaseAddress =3D Page;
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type =3D=3D FaultPte);
+ ASSERT(TempPte.u.Hard.L2.Small.Type =3D=3D SmallPte);
+ *PointerPte =3D TempPte;
+
+ //
+ // Return the address
+ //
+ Address =3D 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;
+ PMMPTE PointerPte;
+ DPRINT1("MmDeleteHyperspaceMapping(%lx)\n", Address);
+ =
+ //
+ // Get the PTE
+ //
+ PointerPte =3D MiGetPteAddress(Address);
+ ASSERT(PointerPte->u.Hard.L2.Small.Type =3D=3D SmallPte);
+ =
+ //
+ // Save the PFN
+ //
+ Pfn =3D PointerPte->u.Hard.L2.Small.BaseAddress;
+ =
+ //
+ // Destroy the PTE
+ //
+ PointerPte->u.Hard.AsUlong =3D 0;
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type =3D=3D FaultPte);
+ =
+ //
+ // Flush the TLB entry and return the PFN
+ //
+ KiFlushSingleTb(TRUE, Address);
+ return Pfn;
+ =
+}
+
+VOID
+NTAPI
+MmInitGlobalKernelPageDirectory(VOID)
+{
+ ULONG i;
+ PULONG CurrentPageDirectory =3D (PULONG)PDE_BASE;
+ =
+ //
+ // Good place to setup template PTE/PDEs.
+ // We are lazy and pick a known-good PTE
+ //
+ MiArmTemplatePte =3D *MiGetPteAddress(0x80000000);
+ MiArmTemplatePde =3D *MiGetPdeAddress(0x80000000);
+
+ //
+ // Loop the 2GB of address space which belong to the kernel
+ //
+ for (i =3D MiGetPdeOffset(MmSystemRangeStart); i < 1024; i++)
+ {
+ //
+ // Check if we have an entry for this already
+ //
+ if ((i !=3D MiGetPdeOffset(PTE_BASE)) &&
+ (i !=3D MiGetPdeOffset(HYPER_SPACE)) &&
+ (!MmGlobalKernelPageDirectory[i]) &&
+ (CurrentPageDirectory[i]))
+ {
+ //
+ // We don't, link it in our global page directory
+ //
+ MmGlobalKernelPageDirectory[i] =3D CurrentPageDirectory[i];
+ }
+ }
+}
+
+ULONG
+NTAPI
+MiGetUserPageDirectoryCount(VOID)
+{
//
// TODO
//
@@ -342,46 +697,59 @@
return 0;
}
=
-PFN_TYPE
-NTAPI
-MmDeleteHyperspaceMapping(IN PVOID Address)
-{
- PFN_TYPE Pfn =3D {0};
- =
- //
- // TODO
- //
- UNIMPLEMENTED;
- return Pfn;
-}
-
-VOID
-NTAPI
-MmInitGlobalKernelPageDirectory(VOID)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
-}
-
-ULONG
-NTAPI
-MiGetUserPageDirectoryCount(VOID)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
-}
-
VOID
NTAPI
MiInitPageDirectoryMap(VOID)
{
- //
- // TODO
- //
- UNIMPLEMENTED;
-}
+ MEMORY_AREA* MemoryArea =3D NULL;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
+ PVOID BaseAddress;
+ NTSTATUS Status;
+ DPRINT1("MiInitPageDirectoryMap()\n");
+
+ //
+ // Create memory area for the PTE area
+ //
+ BoundaryAddressMultiple.QuadPart =3D 0;
+ BaseAddress =3D (PVOID)PTE_BASE;
+ Status =3D 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 =3D (PVOID)PDE_BASE;
+ Status =3D MmCreateMemoryArea(MmGetKernelAddressSpace(),
+ MEMORY_AREA_SYSTEM,
+ &BaseAddress,
+ 0x100000,
+ PAGE_READWRITE,
+ &MemoryArea,
+ TRUE,
+ 0,
+ BoundaryAddressMultiple);
+ ASSERT(NT_SUCCESS(Status));
+ =
+ //
+ // And finally, hyperspace
+ //
+ BaseAddress =3D (PVOID)HYPER_SPACE;
+ Status =3D MmCreateMemoryArea(MmGetKernelAddressSpace(),
+ MEMORY_AREA_SYSTEM,
+ &BaseAddress,
+ PAGE_SIZE,
+ PAGE_READWRITE,
+ &MemoryArea,
+ TRUE,
+ 0,
+ BoundaryAddressMultiple);
+ ASSERT(NT_SUCCESS(Status));
+}
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?=
rev=3D32640&r1=3D32639&r2=3D32640&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/mm/mminit.c (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c Mon Mar 10 12:27:14 2008
@@ -347,9 +347,7 @@
NextEntry =3D NextEntry->Flink)
{
Md =3D CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, =
ListEntry);
- if (Md->MemoryType =3D=3D LoaderBootDriver ||
- Md->MemoryType =3D=3D LoaderSystemCode ||
- Md->MemoryType =3D=3D LoaderHalCode)
+ if (Md->MemoryType !=3D LoaderFree)
{
if (Md->BasePage+Md->PageCount > LastKrnlPhysAddr)
LastKrnlPhysAddr =3D Md->BasePage+Md->PageCount; =
@@ -432,10 +430,13 @@
MmPagedPoolBase =3D (PVOID)PAGE_ROUND_UP((ULONG_PTR)MiNonPagedPoolStar=
t +
MiNonPagedPoolLength);
MmPagedPoolSize =3D MM_PAGED_POOL_SIZE;
+ =
/* Dump kernel memory layout */
MiDbgKernelLayout();
+ =
/* Initialize the page list */
MmInitializePageList();
+ =
/* Unmap low memory */
MmDeletePageTable(NULL, 0);
=