mirror of https://github.com/lianthony/NT4.0
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.
397 lines
11 KiB
397 lines
11 KiB
#if defined(JAZZ)
|
|
|
|
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
jxmemory.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the ARC firmware memory configuration operations
|
|
for a MIPS R3000 or R4000 Jazz system.
|
|
|
|
Author:
|
|
|
|
David N. Cutler (davec) 18-May-1991
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "fwp.h"
|
|
#include "selfmap.h"
|
|
extern end[];
|
|
|
|
//
|
|
// Define memory listhead, allocation entries, and free index.
|
|
//
|
|
|
|
ULONG FwMemoryFree;
|
|
LIST_ENTRY FwMemoryListHead;
|
|
FW_MEMORY_DESCRIPTOR FwMemoryTable[FW_MEMORY_TABLE_SIZE];
|
|
|
|
VOID
|
|
FwInitializeMemory (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the memory allocation list for the memory
|
|
configuration routine.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
ULONG MemoryPages;
|
|
//
|
|
// Initialize the memory allocation listhead.
|
|
//
|
|
|
|
InitializeListHead(&FwMemoryListHead);
|
|
|
|
//
|
|
// Initialize the entry for the exception vectors and the system
|
|
// parameter block.
|
|
//
|
|
|
|
FwMemoryTable[0].MemoryEntry.MemoryType = MemoryFirmwarePermanent;
|
|
|
|
FwMemoryTable[0].MemoryEntry.BasePage = 0;
|
|
FwMemoryTable[0].MemoryEntry.PageCount = 2;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[0].ListEntry);
|
|
|
|
//
|
|
// Initialize the entry for the firmware stack and code.
|
|
//
|
|
|
|
FwMemoryTable[1].MemoryEntry.MemoryType = MemoryFirmwareTemporary;
|
|
|
|
FwMemoryTable[1].MemoryEntry.PageCount = FW_PAGES - 2;
|
|
FwMemoryTable[1].MemoryEntry.BasePage = 2;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[1].ListEntry);
|
|
|
|
//
|
|
// Initialize the entry for free memory and zero the free memory area.
|
|
//
|
|
|
|
FwMemoryTable[2].MemoryEntry.MemoryType = MemoryFree;
|
|
FwMemoryTable[2].MemoryEntry.BasePage = FW_PAGES;
|
|
FwMemoryTable[2].MemoryEntry.PageCount = 0x7ed - FW_PAGES;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[2].ListEntry);
|
|
|
|
//
|
|
// Initialize the entry for the firmware pool.
|
|
//
|
|
|
|
FwMemoryTable[3].MemoryEntry.MemoryType = MemoryFirmwareTemporary;
|
|
FwMemoryTable[3].MemoryEntry.BasePage = 0x7ed;
|
|
FwMemoryTable[3].MemoryEntry.PageCount = 0x7fd - 0x7ed;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[3].ListEntry);
|
|
|
|
//
|
|
// Initialize the entry for the PCR page used by the kernel debugger.
|
|
//
|
|
|
|
FwMemoryTable[4].MemoryEntry.MemoryType = MemoryFirmwareTemporary;
|
|
FwMemoryTable[4].MemoryEntry.BasePage = 0x7fd;
|
|
FwMemoryTable[4].MemoryEntry.PageCount = 0x800 - 0x7fd;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[4].ListEntry);
|
|
|
|
//
|
|
// If the size of memory is greater than 8mb, then generate another
|
|
// descriptor to describe the free memory above the PCR page.
|
|
//
|
|
|
|
if ((MemorySize > 8) && (((ULONG) end & ~KSEG1_BASE) < 0x0800000)) {
|
|
MemoryPages = (MemorySize << (20 - PAGE_SHIFT));
|
|
FwMemoryTable[5].MemoryEntry.MemoryType = MemoryFree;
|
|
FwMemoryTable[5].MemoryEntry.BasePage = 0x800;
|
|
FwMemoryTable[5].MemoryEntry.PageCount = MemoryPages - 0x800;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[5].ListEntry);
|
|
//RtlZeroMemory((PVOID)(KSEG0_BASE + 0x800000),
|
|
// (MemoryPages - 0x800) << PAGE_SHIFT);
|
|
FwMemoryFree = 6;
|
|
|
|
} else if (((ULONG) end & ~KSEG1_BASE) > 0x0800000) {
|
|
|
|
//
|
|
// If this copy of the firmware is loaded above 8 MB, then
|
|
// only part of memory should be zeroed and appropriate memory
|
|
// descriptors should be created.
|
|
//
|
|
// Note: currently all the memory between 800000 and the end
|
|
// of this code is made firmware permanent.
|
|
//
|
|
|
|
FwMemoryTable[5].MemoryEntry.MemoryType = MemoryFirmwarePermanent;
|
|
FwMemoryTable[5].MemoryEntry.BasePage = 0x800;
|
|
FwMemoryTable[5].MemoryEntry.PageCount =
|
|
ROUND_TO_PAGES((ULONG) end & ~KSEG1_BASE) - 0x800;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[5].ListEntry);
|
|
|
|
MemoryPages = (MemorySize << (20 - PAGE_SHIFT));
|
|
FwMemoryTable[6].MemoryEntry.MemoryType = MemoryFree;
|
|
FwMemoryTable[6].MemoryEntry.BasePage = ROUND_TO_PAGES((ULONG) end & ~KSEG1_BASE);
|
|
FwMemoryTable[6].MemoryEntry.PageCount = MemoryPages -
|
|
FwMemoryTable[6].MemoryEntry.BasePage;
|
|
InsertTailList(&FwMemoryListHead, &FwMemoryTable[6].ListEntry);
|
|
//RtlZeroMemory((PVOID)(KSEG0_BASE + (FwMemoryTable[6].MemoryEntry.BasePage << PAGE_SHIFT)),
|
|
// FwMemoryTable[6].MemoryEntry.PageCount << PAGE_SHIFT);
|
|
FwMemoryFree = 7;
|
|
|
|
} else {
|
|
FwMemoryFree = 5;
|
|
}
|
|
|
|
//
|
|
// Initialize the memory configuration routine address in the system
|
|
// parameter block.
|
|
//
|
|
|
|
(PARC_MEMORY_ROUTINE)SYSTEM_BLOCK->FirmwareVector[MemoryRoutine] =
|
|
FwGetMemoryDescriptor;
|
|
|
|
return;
|
|
}
|
|
|
|
PMEMORY_DESCRIPTOR
|
|
FwGetMemoryDescriptor (
|
|
IN PMEMORY_DESCRIPTOR MemoryDescriptor OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a pointer to the next memory descriptor. If
|
|
the specified memory descriptor is NULL, then a pointer to the
|
|
first memory descriptor is returned. If there are no more memory
|
|
descriptors, then NULL is returned.
|
|
|
|
Arguments:
|
|
|
|
MemoryDescriptor - Supplies a optional pointer to a memory descriptor.
|
|
|
|
Return Value:
|
|
|
|
If there are any more entries in the memory descriptor list, the
|
|
address of the next descriptor is returned. Otherwise, NULL is
|
|
returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PFW_MEMORY_DESCRIPTOR TableEntry;
|
|
PLIST_ENTRY NextEntry;
|
|
|
|
//
|
|
// If a memory descriptor address is specified, then return the
|
|
// address of the next descriptor or NULL as appropriate. Otherwise,
|
|
// return the address of the first memory descriptor.
|
|
//
|
|
|
|
if (ARGUMENT_PRESENT(MemoryDescriptor)) {
|
|
TableEntry = CONTAINING_RECORD(MemoryDescriptor,
|
|
FW_MEMORY_DESCRIPTOR,
|
|
MemoryEntry);
|
|
|
|
NextEntry = TableEntry->ListEntry.Flink;
|
|
if (NextEntry != &FwMemoryListHead) {
|
|
return &(CONTAINING_RECORD(NextEntry,
|
|
FW_MEMORY_DESCRIPTOR,
|
|
ListEntry)->MemoryEntry);
|
|
|
|
} else {
|
|
return NULL;
|
|
}
|
|
|
|
} else {
|
|
return &FwMemoryTable[0].MemoryEntry;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FwGenerateDescriptor (
|
|
IN PFW_MEMORY_DESCRIPTOR MemoryDescriptor,
|
|
IN MEMORY_TYPE MemoryType,
|
|
IN ULONG BasePage,
|
|
IN ULONG PageCount
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allocates a new memory descriptor to describe the
|
|
specified region of memory which is assumed to lie totally within
|
|
the specified region which is free.
|
|
|
|
Arguments:
|
|
|
|
MemoryDescriptor - Supplies a pointer to a free memory descriptor
|
|
from which the specified memory is to be allocated.
|
|
|
|
MemoryType - Supplies the type that is assigned to the allocated
|
|
memory.
|
|
|
|
BasePage - Supplies the base page number.
|
|
|
|
PageCount - Supplies the number of pages.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PLIST_ENTRY NextEntry;
|
|
ULONG Offset;
|
|
|
|
//
|
|
// If the specified region totally consumes the free region, then no
|
|
// additional descriptors need to be allocated. If the specified region
|
|
// is at the start or end of the free region, then only one descriptor
|
|
// needs to be allocated. Otherwise, two additional descriptors need to
|
|
// be allocated.
|
|
//
|
|
|
|
Offset = BasePage - MemoryDescriptor->MemoryEntry.BasePage;
|
|
if ((Offset == 0) && (PageCount == MemoryDescriptor->MemoryEntry.PageCount)) {
|
|
|
|
//
|
|
// The specified region totally consumes the free region.
|
|
//
|
|
|
|
MemoryDescriptor->MemoryEntry.MemoryType = MemoryType;
|
|
|
|
} else {
|
|
|
|
//
|
|
// A memory descriptor must be generated to describe the allocated
|
|
// memory.
|
|
//
|
|
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.MemoryType = MemoryType;
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.BasePage = BasePage;
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.PageCount = PageCount;
|
|
InsertTailList(&FwMemoryListHead,
|
|
&FwMemoryTable[FwMemoryFree].ListEntry);
|
|
|
|
FwMemoryFree += 1;
|
|
|
|
//
|
|
// Determine whether an additional memory descriptor must be generated.
|
|
//
|
|
|
|
if (BasePage == MemoryDescriptor->MemoryEntry.BasePage) {
|
|
|
|
//
|
|
// The specified region lies at the start of the free region.
|
|
//
|
|
|
|
MemoryDescriptor->MemoryEntry.BasePage += PageCount;
|
|
MemoryDescriptor->MemoryEntry.PageCount -= PageCount;
|
|
|
|
} else if ((Offset + PageCount) == MemoryDescriptor->MemoryEntry.PageCount) {
|
|
|
|
//
|
|
// The specified region lies at the end of the free region.
|
|
//
|
|
|
|
MemoryDescriptor->MemoryEntry.PageCount -= PageCount;
|
|
|
|
} else {
|
|
|
|
//
|
|
// The specified region lies in the middle of the free region.
|
|
// Another memory descriptor must be generated.
|
|
//
|
|
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.MemoryType = MemoryFree;
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.BasePage = BasePage + PageCount;
|
|
FwMemoryTable[FwMemoryFree].MemoryEntry.PageCount =
|
|
MemoryDescriptor->MemoryEntry.PageCount -
|
|
(PageCount + Offset);
|
|
InsertTailList(&FwMemoryListHead,
|
|
&FwMemoryTable[FwMemoryFree].ListEntry);
|
|
|
|
FwMemoryFree += 1;
|
|
MemoryDescriptor->MemoryEntry.PageCount = Offset;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
FwResetMemory(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls FwInitializeMemory to reset the memory descriptors
|
|
and then loops through and clears all of the appropriate memory.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMEMORY_DESCRIPTOR MemoryDescriptor;
|
|
|
|
FwInitializeMemory();
|
|
|
|
//
|
|
// Reset all memory not used by the firmware.
|
|
// TEMPTEMP Just reset under 8M Bytes for now.
|
|
//
|
|
|
|
MemoryDescriptor = FwGetMemoryDescriptor(NULL);
|
|
while (MemoryDescriptor != NULL) {
|
|
|
|
if ((MemoryDescriptor->MemoryType != MemoryFirmwarePermanent) &&
|
|
(MemoryDescriptor->MemoryType != MemoryFirmwareTemporary) &&
|
|
(MemoryDescriptor->BasePage < 0x800)) {
|
|
RtlZeroMemory((PVOID)(KSEG0_BASE + (MemoryDescriptor->BasePage << PAGE_SHIFT)),
|
|
MemoryDescriptor->PageCount << PAGE_SHIFT);
|
|
}
|
|
|
|
MemoryDescriptor = FwGetMemoryDescriptor(MemoryDescriptor);
|
|
}
|
|
|
|
//
|
|
// Sweep the data cache
|
|
//
|
|
|
|
HalSweepDcache();
|
|
|
|
}
|
|
#endif
|