diff options
Diffstat (limited to 'private/ntos/nthals/halncr/i386/ncrlarc.c')
-rw-r--r-- | private/ntos/nthals/halncr/i386/ncrlarc.c | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/private/ntos/nthals/halncr/i386/ncrlarc.c b/private/ntos/nthals/halncr/i386/ncrlarc.c new file mode 100644 index 000000000..e486fcdbc --- /dev/null +++ b/private/ntos/nthals/halncr/i386/ncrlarc.c @@ -0,0 +1,392 @@ +/*++ + +Copyright (c) 1992 NCR Corporation + +Module Name: + + ncrlarc.c + +Abstract: + + +Author: + + Rick Ulmer + +Environment: + + Kernel mode only. + +Revision History: + +--*/ + +//#include "halp.h" +#include "ki.h" +#include "stdio.h" +#include "ncr.h" +#include "ncrcat.h" +#include "ncrsus.h" + +extern PPROCESSOR_BOARD_INFO SUSBoardInfo; +extern ULONG NCRLogicalDyadicProcessorMask; +extern ULONG NCRLogicalQuadProcessorMask; +extern ULONG NCRLogicalNumberToPhysicalMask[]; +extern ULONG NCRExistingQuadProcessorMask; +extern ULONG NCRActiveProcessorMask; + +extern ULONG NCRLarcPageMask; + +#define PASS_LARC_TEST 1 +#define LARC_TEST 2 +#define LARC_BANK0 4 +#define LARC_BANK1 8 +#define LARC_8MB 0x80 +#define LARC_2MB 0x40 +#define LARC_PAGES 8 +#define LARC_TIMEOUT 40000 // This is what the UNIX Guys use. + + +ULONG NCRLarcEnabledPages[8] = {0}; // LARC size by Voyager slot + + +PCHAR +NCRUnicodeToAnsi( + IN PUNICODE_STRING UnicodeString, + OUT PCHAR AnsiBuffer, + IN ULONG MaxAnsiLength + ) +{ + PCHAR Dst; + PWSTR Src; + ULONG Length; + + Length = UnicodeString->Length / sizeof( WCHAR ); + if (Length >= MaxAnsiLength) { + Length = MaxAnsiLength - 1; + } + Src = UnicodeString->Buffer; + Dst = AnsiBuffer; + while (Length--) { + *Dst++ = (UCHAR)*Src++; + } + *Dst = '\0'; + return AnsiBuffer; +} + + + +VOID +HalpInitializeLarc ( + ) +/*++ + +Routine Description: + Initialize any Larc's that may exist on any Quad processor boards + +Arguments: + none. + +Return Value: + none. + +--*/ + +{ + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Next; + PLDR_DATA_TABLE_ENTRY DataTableEntry; + CHAR Buffer[256]; + UCHAR AnsiBuffer[ 32 ]; + ULONG i; + PHYSICAL_ADDRESS kernel_physical; + ULONG base; + UCHAR addr[2]; + CAT_CONTROL cat_control; + LONG status; + UCHAR data; + UCHAR enable; + BOOLEAN larc_found = FALSE; + ULONG timeout_count; + LONG pages, page, banks; + + DBGMSG(("HalpInitializeLarc: KeLoaderBlock = 0x%x\n",KeLoaderBlock)); + + // + // Dump the loaded module list + // + + if (KeLoaderBlock != NULL) { + ModuleListHead = &KeLoaderBlock->LoadOrderListHead; + + } else { + DBGMSG(("HalpInitializeLarc: KeLoaderBlock is NULL returning...\n")); + return; + } + + Next = ModuleListHead->Flink; + + if (Next != NULL) { + + i = 0; + + DBGMSG(("HalpInitializeLarc: ModuleListHead = 0x%x\n", ModuleListHead)); + + DBGMSG(("HalpInitializeLarc: Next = 0x%x\n", Next)); + while (Next != ModuleListHead) { + + DataTableEntry = CONTAINING_RECORD(Next, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + sprintf (Buffer, "HalpInitializeLarc: Name: %s Base: 0x%x\n", + NCRUnicodeToAnsi(&DataTableEntry->BaseDllName,AnsiBuffer,sizeof(AnsiBuffer)), + DataTableEntry->DllBase + ); + + DBGMSG((Buffer)); + + if (strncmp(AnsiBuffer,"ntoskrnl",8) == 0) { + kernel_physical = MmGetPhysicalAddress(DataTableEntry->DllBase); + + DBGMSG(("HalpInitializeLarc: Found kernel at Virtual address 0x%x and Physical Address 0x%x\n", + DataTableEntry->DllBase, + kernel_physical.LowPart)); + break; + } + + if (i++ == 30) { + DBGMSG(("HalpInitializeLarc: ModuleList too long breaking out\n")); + break; + } + Next = Next->Flink; + DBGMSG(("HalpInitializeLarc: Next = 0x%x\n", Next)); + } + } + + base = 0xffc00000 & kernel_physical.LowPart; // round down to 4MB boundary + + addr[0] = base >> 24; + addr[1] = base >> 16; + +// +// Lets check for larc info +// + + DBGMSG(("HalpInitializeLarc: Lets look to Quad boards and larc\n")); + + for (i = 0; i < SUSBoardInfo->NumberOfBoards; i++ ) { + if (SUSBoardInfo->QuadData[i].Type != QUAD) { + continue; + } + switch (SUSBoardInfo->QuadData[i].Slot) { + case 1: + cat_control.Module = QUAD_BB0; + break; + case 2: + cat_control.Module = QUAD_BB1; + break; + case 3: + cat_control.Module = QUAD_BB2; + break; + case 4: + cat_control.Module = QUAD_BB3; + break; + } + cat_control.Asic = QABC; + + // + // get LARC bank info + // + + cat_control.Command = READ_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x3; + status = HalCatBusIo(&cat_control, &enable); + + if (((enable & (LARC_BANK0|LARC_BANK1)) == 0) || (status != CATNOERR)) { + // + // no LARC on this board + // + continue; + } + + larc_found = TRUE; + + DBGMSG(("HalpInitializeLarc: Found LARC in Slot %d, with Self_test Reg = 0x%x\n", + SUSBoardInfo->QuadData[i].Slot, + enable)); + // + // Disable all 4MB pages + // + + + data = 0; + cat_control.Command = WRITE_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x0; + status = HalCatBusIo(&cat_control, &data); + + // + // Set new LARC base + // + + cat_control.NumberOfBytes = 2; + cat_control.Address = 0x1; + status = HalCatBusIo(&cat_control, addr); + + // + // now lets test the LARC + // + + enable |= LARC_TEST; // Run LARC test + + cat_control.Command = WRITE_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x3; + status = HalCatBusIo(&cat_control, &enable); + } + + + if (!larc_found) { + return; + } + + // + // lets wait for all LARC test to complete + // + + DBGMSG(("HalpInitializeLarc: Now waiting for LARC self-test to complete.\n")); + + for (i = 0; i < SUSBoardInfo->NumberOfBoards; i++ ) { + if (SUSBoardInfo->QuadData[i].Type != QUAD) { + continue; + } + switch (SUSBoardInfo->QuadData[i].Slot) { + case 1: + cat_control.Module = QUAD_BB0; + break; + case 2: + cat_control.Module = QUAD_BB1; + break; + case 3: + cat_control.Module = QUAD_BB2; + break; + case 4: + cat_control.Module = QUAD_BB3; + break; + } + cat_control.Asic = QABC; + + cat_control.Command = READ_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x3; + timeout_count = 0; + + do { + status = HalCatBusIo(&cat_control, &enable); + if (status != CATNOERR) { + return; + } + if ((enable & (LARC_BANK0|LARC_BANK1)) == 0) { + break; // no LARC on this QUAD board + } + } while ((enable & LARC_TEST) && (++timeout_count < LARC_TIMEOUT)); + DBGMSG(("HalpInitializeLarc: LARC in slot %d, complete: enable = 0x%x, timeout_count =%d\n", + SUSBoardInfo->QuadData[i].Slot, enable, timeout_count)); + } + DBGMSG(("HalpInitializeLarc: All LARCS test complete.....\n")); + + + + // + // Lets enable the LARCS + // + + DBGMSG(("HalpInitializeLarc: Now Enabling LARC pages\n")); + + for (i = 0; i < SUSBoardInfo->NumberOfBoards; i++ ) { + if (SUSBoardInfo->QuadData[i].Type != QUAD) { + continue; + } + switch (SUSBoardInfo->QuadData[i].Slot) { + case 1: + cat_control.Module = QUAD_BB0; + break; + case 2: + cat_control.Module = QUAD_BB1; + break; + case 3: + cat_control.Module = QUAD_BB2; + break; + case 4: + cat_control.Module = QUAD_BB3; + break; + } + cat_control.Asic = QABC; + + cat_control.Command = READ_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x3; + status = HalCatBusIo(&cat_control, &enable); + + if (((enable & (LARC_BANK0|LARC_BANK1)) == 0) || (status != CATNOERR)) { + // + // no LARC on this board + // + continue; + } + + if ((enable & PASS_LARC_TEST) == 0) { + // + // this LARC did not pass self-test + // + continue; + } + + + if (enable & LARC_BANK0) { + banks = 1; + } else { + banks = 0; + } + + if (enable & LARC_BANK1) { + banks += 1; + } + + if (enable & LARC_8MB) { + pages = 4 * banks; + } else { + pages = banks; + } + + cat_control.Command = READ_SUBADDR; + cat_control.NumberOfBytes = 1; + cat_control.Address = 0x0; + status = HalCatBusIo(&cat_control, &enable); + + DBGMSG(("HalpInitializeLarc: banks = %d, pages = %d\n",banks, pages)); + + NCRLarcEnabledPages[SUSBoardInfo->QuadData[i].Slot-1] = pages; + + for (page = 1; pages > 0; page <<= 1, pages--) { + enable |= page; + } + + enable &= NCRLarcPageMask; // now apply enable mask + + cat_control.Command = WRITE_SUBADDR; + + DBGMSG(("HalpInitializeLarc: Slot %d, enable Mask = 0x%x\n", + SUSBoardInfo->QuadData[i].Slot, + enable)); + + status = HalCatBusIo(&cat_control, &enable); + } + + DBGMSG(("HalpInitializeLarc: Done\n")); +} + + + |