summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halncr/i386/ncrlarc.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halncr/i386/ncrlarc.c')
-rw-r--r--private/ntos/nthals/halncr/i386/ncrlarc.c392
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"));
+}
+
+
+