summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsnip/mips/xxmemory.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/halsnip/mips/xxmemory.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/nthals/halsnip/mips/xxmemory.c')
-rw-r--r--private/ntos/nthals/halsnip/mips/xxmemory.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/private/ntos/nthals/halsnip/mips/xxmemory.c b/private/ntos/nthals/halsnip/mips/xxmemory.c
new file mode 100644
index 000000000..2d9806212
--- /dev/null
+++ b/private/ntos/nthals/halsnip/mips/xxmemory.c
@@ -0,0 +1,246 @@
+//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/halpcims/src/hal/halsnipm/mips/RCS/xxmemory.c,v 1.2 1996/02/23 17:55:12 pierre Exp $")
+
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ xxmemory.c
+
+Abstract:
+
+ Provides routines to allow the HAL to map physical memory.
+
+Environment:
+
+ Phase 0 initialization only.
+
+Changes:
+
+ All stuff comes from the x86 HAL Sources (xxmemory.c)
+
+--*/
+#include "halp.h"
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(INIT, HalpAllocPhysicalMemory)
+#endif
+
+
+MEMORY_ALLOCATION_DESCRIPTOR HalpExtraAllocationDescriptor;
+
+ULONG
+HalpAllocPhysicalMemory(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN ULONG MaxPhysicalAddress,
+ IN ULONG NoPages,
+ IN BOOLEAN bAlignOn64k
+ )
+/*++
+
+Routine Description:
+
+ Carves out N pages of physical memory from the memory descriptor
+ list in the desired location. This function is to be called only
+ during phase zero initialization. (ie, before the kernel's memory
+ management system is running)
+
+Arguments:
+
+ MaxPhysicalAddress - The max address where the physical memory can be
+ NoPages - Number of pages to allocate
+
+Return Value:
+
+ The pyhsical address or NULL if the memory could not be obtained.
+
+--*/
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ PLIST_ENTRY NextMd;
+ ULONG AlignmentOffset;
+ ULONG MaxPageAddress;
+ ULONG PhysicalAddress;
+
+
+ MaxPageAddress = MaxPhysicalAddress >> PAGE_SHIFT;
+
+
+ //
+ // Scan the memory allocation descriptors and allocate map buffers
+ //
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
+ Descriptor = CONTAINING_RECORD(NextMd,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ AlignmentOffset = bAlignOn64k ?
+ ((Descriptor->BasePage + 0x0f) & ~0x0f) - Descriptor->BasePage :
+ 0;
+
+ //
+ // Search for a block of memory which contains a memory chunk
+ // that is greater than size pages, and has a physical address less
+ // than MAXIMUM_PHYSICAL_ADDRESS.
+ //
+
+ if ((Descriptor->MemoryType == LoaderFree ||
+ Descriptor->MemoryType == MemoryFirmwareTemporary) &&
+ (Descriptor->BasePage) &&
+ (Descriptor->PageCount >= NoPages + AlignmentOffset) &&
+ (Descriptor->BasePage + NoPages + AlignmentOffset < MaxPageAddress)) {
+
+ PhysicalAddress = (AlignmentOffset + Descriptor->BasePage)
+ << PAGE_SHIFT;
+
+ break;
+ }
+
+ NextMd = NextMd->Flink;
+ }
+
+ //
+ // Use the extra descriptor to define the memory at the end of the
+ // original block.
+ //
+
+
+ ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
+
+ if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
+
+ return (ULONG)NULL;
+
+ //
+ // Adjust the memory descriptors.
+ //
+
+ if (AlignmentOffset == 0) {
+
+ Descriptor->BasePage += NoPages;
+ Descriptor->PageCount -= NoPages;
+
+ if (Descriptor->PageCount == 0) {
+
+ //
+ // The whole block was allocated,
+ // Remove the entry from the list completely.
+ //
+
+ RemoveEntryList(&Descriptor->ListEntry);
+
+ }
+
+ } else {
+
+ if (Descriptor->PageCount - NoPages - AlignmentOffset) {
+
+ //
+ // Currently we only allow one Align64K allocation
+ //
+ ASSERT (HalpExtraAllocationDescriptor.PageCount == 0);
+
+ //
+ // The extra descriptor is needed so intialize it and insert
+ // it in the list.
+ //
+ HalpExtraAllocationDescriptor.PageCount =
+ Descriptor->PageCount - NoPages - AlignmentOffset;
+
+ HalpExtraAllocationDescriptor.BasePage =
+ Descriptor->BasePage + NoPages + AlignmentOffset;
+
+ HalpExtraAllocationDescriptor.MemoryType = MemoryFree;
+ InsertTailList(
+ &Descriptor->ListEntry,
+ &HalpExtraAllocationDescriptor.ListEntry
+ );
+ }
+
+
+ //
+ // Use the current entry as the descriptor for the first block.
+ //
+
+ Descriptor->PageCount = AlignmentOffset;
+ }
+
+
+ return PhysicalAddress;
+}
+
+
+#define MEMBASE 0x20000000
+
+USHORT HalpComputeNum (phys_addr)
+UCHAR *phys_addr;
+{
+ USHORT board_or_simm_num;
+ ULONG i;
+ struct bank *pbank =((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->MemConfArea;
+ ULONG nb_banks =((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))-> NbMemBanks;
+ UCHAR *conf_addr;
+
+
+
+ if (pbank == 0) return((USHORT)(-1)); // firmware revision < 4.5 --> function non implemented
+
+
+ // Rebase phys_addr at 0x20000000
+ (ULONG)phys_addr |= MEMBASE;
+
+ for (i = 0; i < nb_banks; i++, pbank++) {
+
+ // Rebase conf_addr at 0x20000000
+ conf_addr =(UCHAR *)( (ULONG)pbank->first_addr | MEMBASE);
+
+ if ((phys_addr >= conf_addr) && (phys_addr < (conf_addr + pbank->first_piece_size))){
+
+ break;
+ }
+
+ if (pbank->second_piece_size != 0) {
+
+ // Rebase conf_addr at 0x20000000
+ conf_addr =(UCHAR *)((ULONG) pbank->second_addr | MEMBASE);
+
+ if ((phys_addr >= conf_addr) && (phys_addr < (conf_addr + pbank->second_piece_size))) {
+
+ break;
+ }
+ }
+ }
+
+ if (i == nb_banks) {
+
+ // Unable to find the board or SIMM
+ board_or_simm_num = (USHORT)(-1);
+ }
+
+ else {
+ // On RM400 we have one board per bank from 1 to nb_banks
+ if (HalpIsTowerPci) {
+ board_or_simm_num = (USHORT)(i + 1);
+ }
+ // On RM200/RM300 we have two SIMM's per bank from 0 to 2*nb_banks - 1
+ else {
+ board_or_simm_num = (USHORT)( (2*i) + (((ULONG)phys_addr >> 3) & 0x01));
+ }
+ }
+
+ return (board_or_simm_num);
+}
+
+
+
+
+