Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Module Name:
intimap.c
Abstract:
This module initializes the system process mapping for a 64-bit Alpha system.
Author:
David N. Cutler (davec) 5-Jan-1998
Environment:
Kernel mode only.
Revision History:
--*/
#include "bldr.h"
#include "arc.h"
//
// Define size of page map.
//
#define PD_INDEX(va) (((va) >> PDI2_SHIFT) & PDI_MASK)
#define PAGE_MAP_SIZE (PD_INDEX(KSEG2_BASE) - PD_INDEX(KSEG0_BASE))
ARC_STATUS BlInitializeSystemProcessMap ( IN PLOADER_PARAMETER_BLOCK LoaderBlock )
/*++
Routine Description:
This function initializes the system process map for 64-bit Alpha systems.
Arguments:
LoaderBlock - Supplies a pointer to the loader parameter block.
Return Value:
None.
--*/
{
ULONG Base; ULONG Count; PMEMORY_ALLOCATION_DESCRIPTOR Descriptor; ULONG Index; PLIST_ENTRY ListHead; UCHAR PageMap[PAGE_MAP_SIZE]; PLIST_ENTRY NextEntry; ULONG Number; PHARDWARE_PTE Pdr1; PHARDWARE_PTE Pdr2; PHARDWARE_PTE Ptp; ULONG PdrPage; ARC_STATUS Status; ULONG Total;
//
// On 64-bit Alpha systems a three level mapping structure is used
// and up to 1gb of physical memory is identity mapped into KSEG0
// for PAL code access.
//
// One page is required for the first level page directory.
//
// One page is required for the kernel second level page directory.
//
// One page is required for each page table page in the identify map.
//
// One page is required for the page table page to map the shared page.
//
// One page is required for the shared page.
//
// Locate all pages in the first 1gb of physical memory and record
// page table page usage.
//
RtlZeroMemory(&PageMap[0], PAGE_MAP_SIZE); ListHead = &LoaderBlock->MemoryDescriptorListHead; NextEntry = ListHead->Flink; do { Descriptor = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
Number = Descriptor->BasePage; for (Count = 0; Count < Descriptor->PageCount; Count += 1) { Index = Number >> (PDI2_SHIFT - PTI_SHIFT); if (Index < PAGE_MAP_SIZE) { PageMap[Index] = 1; }
Number += 1; }
NextEntry = NextEntry->Flink; } while (NextEntry != ListHead);
//
// Compute the number of page table pages required to map the first
// 1gb of physical memory.
//
Total = 4; for (Count = 0; Count < PAGE_MAP_SIZE; Count += 1) { Total += PageMap[Count]; }
//
// Allocate a level 1 page directory page, a level 2 page directory
// page, a shared page table page, a shared data page, and the required
// number of pages to map up to 1gb of physical
// memory.
//
Status = BlAllocateAnyMemory(LoaderStartupPdrPage, 0, Total, &LoaderBlock->u.Alpha.PdrPage);
if (Status != ESUCCESS) { return Status; }
//
// Self map the level 1 directory into the level 1 directory, map the
// level 2 kernel page directory page into the level 1 page directory
// page, map the shared data page table page, and map all the
// page table pages into the level 2 page directory page so the first 1gb
// of physical memory can be accessed via KSEG0.
//
// Compute the address of the level one page directory page and zero
// the page.
//
PdrPage = LoaderBlock->u.Alpha.PdrPage; Pdr1 = (PHARDWARE_PTE)(KSEG0_BASE | (PdrPage << PAGE_SHIFT)); RtlZeroMemory(Pdr1, PAGE_SIZE);
//
// Map the level one page directory identity entry in the level one
// page directory page.
//
Index = (PDE_BASE >> PDI1_SHIFT) & PDI_MASK; Pdr1[Index].Valid = 1; Pdr1[Index].KernelReadAccess = 1; Pdr1[Index].KernelWriteAccess = 1; Pdr1[Index].Write = 1; Pdr1[Index].PageFrameNumber = PdrPage++;
//
// Map the level two kernel page directory page entry in the level one
// page directory page.
//
Index = (KSEG0_BASE >> PDI1_SHIFT) & PDI_MASK; Pdr1[Index].Valid = 1; Pdr1[Index].KernelReadAccess = 1; Pdr1[Index].KernelWriteAccess = 1; Pdr1[Index].Write = 1; Pdr1[Index].PageFrameNumber = PdrPage;
//
// Compute the address of the level two kernel page directory page and
// zero the page.
//
Pdr2 = (PHARDWARE_PTE)(KSEG0_BASE | (PdrPage++ << PAGE_SHIFT)); RtlZeroMemory(Pdr2, PAGE_SIZE);
//
// Map the shared data page table page in the level two kernel page
// directory page.
//
Index = (KI_USER_SHARED_DATA >> PDI2_SHIFT) & PDI_MASK; Pdr2[Index].Valid = 1; Pdr2[Index].Global = 1; Pdr2[Index].KernelReadAccess = 1; Pdr2[Index].KernelWriteAccess = 1; Pdr2[Index].Write = 1; Pdr2[Index].PageFrameNumber = PdrPage;
//
// Compute the address of the shared data page table page and zero
// the page.
//
Ptp = (PHARDWARE_PTE)(KSEG0_BASE | (PdrPage++ << PAGE_SHIFT)); RtlZeroMemory(Ptp, PAGE_SIZE);
//
// Map the shared data page in the shared data page table page.
//
Index = (KI_USER_SHARED_DATA >> PTI_SHIFT) & PDI_MASK; Ptp[Index].Valid = 1; Ptp[Index].Global = 1; Ptp[Index].KernelReadAccess = 1; Ptp[Index].KernelWriteAccess = 1; Ptp[Index].Write = 1; Ptp[Index].PageFrameNumber = PdrPage;
//
// Compute the address of the shared data page and zero the page.
//
Ptp = (PHARDWARE_PTE)(KSEG0_BASE | (PdrPage++ << PAGE_SHIFT)); RtlZeroMemory(Ptp, PAGE_SIZE);
//
// Construct the identity map for the first 1gb of physical memory.
//
Base = (KSEG0_BASE >> PDI2_SHIFT) & PDI_MASK; for (Count = 0; Count < PAGE_MAP_SIZE; Count += 1) { if (PageMap[Count] != 0) { Pdr2[Base | Count].Valid = 1; Pdr2[Base | Count].Global = 1; Pdr2[Base | Count].KernelReadAccess = 1; Pdr2[Base | Count].KernelWriteAccess = 1; Pdr2[Base | Count].Write = 1; Pdr2[Base | Count].PageFrameNumber = PdrPage; Ptp = (PHARDWARE_PTE)(KSEG0_BASE | (PdrPage << PAGE_SHIFT)); RtlZeroMemory(Ptp, PAGE_SIZE); PdrPage += 1; } }
//
// Identity map the first 1gb of physical memory into KSEG0.
//
ListHead = &LoaderBlock->MemoryDescriptorListHead; NextEntry = ListHead->Flink; do { Descriptor = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
Number = Descriptor->BasePage; for (Count = 0; Count < Descriptor->PageCount; Count += 1) { Index = Number >> (PDI2_SHIFT - PTI_SHIFT); if (Index < PAGE_MAP_SIZE) { Ptp = (PHARDWARE_PTE)(KSEG0_BASE | (Pdr2[Base | Index].PageFrameNumber << PAGE_SHIFT)); Index = Number & PDI_MASK; Ptp[Index].Valid = 1; Ptp[Index].Global = 1; Ptp[Index].KernelReadAccess = 1; Ptp[Index].KernelWriteAccess = 1; Ptp[Index].Write = 1; Ptp[Index].PageFrameNumber = Number; }
Number += 1; }
NextEntry = NextEntry->Flink; } while (NextEntry != ListHead);
//
// Set the granularity hint bits.
//
BlSetGranularityHints(Pdr1, Total); return ESUCCESS; }
|