NT4/private/ntos/fw/mips/jxmemory.c
2020-09-30 17:12:29 +02:00

398 lines
11 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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