summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/haloli/i386/olisproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/haloli/i386/olisproc.c')
-rw-r--r--private/ntos/nthals/haloli/i386/olisproc.c581
1 files changed, 581 insertions, 0 deletions
diff --git a/private/ntos/nthals/haloli/i386/olisproc.c b/private/ntos/nthals/haloli/i386/olisproc.c
new file mode 100644
index 000000000..1de78859f
--- /dev/null
+++ b/private/ntos/nthals/haloli/i386/olisproc.c
@@ -0,0 +1,581 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ olisproc.c
+
+Abstract:
+
+ SystemPro Start Next Processor c code.
+
+ This module implements the initialization of the system dependent
+ functions that define the Hardware Architecture Layer (HAL) for an
+ MP Compaq SystemPro
+
+Author:
+
+ Ken Reneris (kenr) 22-Jan-1991
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Bruno Sartirana (o-obruno) 3-Mar-92
+ Added support for the Olivetti LSX5030.
+--*/
+
+#include "halp.h"
+
+UCHAR HalName[] = "Olivetti LSX5030 MP Hal";
+
+
+VOID
+HalpMapCR3 (
+ IN ULONG VirtAddress,
+ IN PVOID PhysicalAddress,
+ IN ULONG Length
+ );
+
+ULONG
+HalpBuildTiledCR3 (
+ IN PKPROCESSOR_STATE ProcessorState
+ );
+
+VOID
+HalpFreeTiledCR3 (
+ VOID
+ );
+
+//LSX5030 start
+
+
+ULONG
+HalpGetIpiIrqNumber();
+
+VOID
+HalpIpiHandler(
+ VOID
+ );
+
+ULONG
+HalpGetNumberOfProcessors();
+
+
+#ifdef HALOLI_DBG
+
+VOID
+DbgDisplay(
+ IN UCHAR Code
+ );
+# define DBG_DISPLAY(x) DbgDisplay(x)
+#else
+# define DBG_DISPLAY(x)
+#endif
+
+
+
+/***
+ * Olivetti LSX5030 varialbles and constants
+ */
+
+
+
+ULONG IpiVector; // Inter-processor interrupt vector
+ULONG IdtIpiVector; // Inter-processor interrupt vector # in
+ // the IDT
+ULONG HalpCpuCount; // total number of CPU's available
+ULONG CpuLeft; // number of CPU's not started yet
+ULONG NextCpuToStart = 1; // next CPU logical # to start
+
+
+// LSX5030 end
+
+
+
+#define LOW_MEMORY 0x000100000
+#define MAX_PT 8
+
+extern VOID __cdecl StartPx_PMStub(VOID);
+
+
+PUCHAR MpLowStub; // pointer to low memory bootup stub
+PVOID MpLowStubPhysicalAddress; // pointer to low memory bootup stub
+PUCHAR MppIDT; // pointer to physical memory 0:0
+PVOID MpFreeCR3[MAX_PT]; // remember pool memory to free
+
+
+
+BOOLEAN
+HalpInitMP (
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+/*++
+
+Routine Description:
+ Allows MP initialization from HalInitSystem.
+
+Arguments:
+ Same as HalInitSystem
+
+Return Value:
+ none.
+
+--*/
+{
+ PKPCR pPCR;
+ KIRQL CurrentIrql;
+
+
+ pPCR = KeGetPcr();
+
+ if (Phase == 0) {
+
+ //
+ // Only Processor 0 runs the phase 0 initializtion code
+ //
+
+ //DBG_DISPLAY(0x00);
+ MppIDT = HalpMapPhysicalMemory (0, 1);
+
+//LSX5030 start
+ IpiVector = HalpGetIpiIrqNumber();
+ IdtIpiVector = IpiVector + PRIMARY_VECTOR_BASE;
+
+ HalpCpuCount = HalpGetNumberOfProcessors();
+ CpuLeft = HalpCpuCount - 1;
+
+ if (CpuLeft == 0) {
+
+ //
+ // Only 1 CPU available
+ //
+
+ return TRUE;
+ }
+
+
+ //
+ // Register IPI handler
+ //
+
+ KiSetHandlerAddressToIDT(PRIMARY_VECTOR_BASE + IpiVector,
+ HalpIpiHandler);
+
+ //
+ // Enable inter-processor interrupts on CPU 0
+ //
+
+ HalEnableSystemInterrupt(PRIMARY_VECTOR_BASE + IpiVector,
+ IPI_LEVEL, 0);
+
+//LSX5030 end
+
+ //
+ // Allocate some low memory for processor bootup stub
+ //
+
+ MpLowStubPhysicalAddress = (PVOID)HalpAllocPhysicalMemory (LoaderBlock,
+ LOW_MEMORY, 1, FALSE);
+
+ if (!MpLowStubPhysicalAddress)
+ return TRUE;
+
+ MpLowStub = (PCHAR) HalpMapPhysicalMemory (MpLowStubPhysicalAddress, 1);
+
+ } else {
+
+ //
+ // Phase 1
+ //
+
+ //DBG_DISPLAY(0x10);
+ //
+ // Check to see if this is not processor 0
+ //
+
+ if (pPCR->Prcb->Number != 0) {
+
+ //DBG_DISPLAY(0x11);
+ //
+ // It is not processor 0. Mask the PICs and start the clock.
+ //
+
+ //
+ // Mask the PICs to reflect the current Irql
+ //
+
+ CurrentIrql = KeGetCurrentIrql();
+ CurrentIrql = KfRaiseIrql (CurrentIrql);
+
+
+ //
+ // Initialize the timer 1 counter 0
+ //
+
+ HalpInitializeClock();
+ //DBG_DISPLAY(0x12);
+
+ //
+ // Initialize the clock interrupt vector and enable the
+ // clock interrupt.
+ //
+
+ KiSetHandlerAddressToIDT(CLOCK_VECTOR, HalpClockInterrupt );
+ HalEnableSystemInterrupt(CLOCK_VECTOR, CLOCK2_LEVEL, Latched);
+ //DBG_DISPLAY(0x13);
+ }
+ }
+ return TRUE;
+}
+
+VOID
+HalReportResourceUsage (
+ VOID
+ )
+/*++
+
+Routine Description:
+ The registery is now enabled - time to report resources which are
+ used by the HAL.
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ ANSI_STRING AHalName;
+ UNICODE_STRING UHalName;
+
+ HalInitSystemPhase2 ();
+
+ RtlInitAnsiString (&AHalName, HalName);
+ RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
+
+ HalpReportResourceUsage (
+ &UHalName, // descriptive name
+ Eisa // The LSX5030 is an Eisa machine
+ );
+
+ RtlFreeUnicodeString (&UHalName);
+
+}
+
+
+BOOLEAN
+HalAllProcessorsStarted (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+
+VOID
+HalpResetAllProcessors (
+ VOID
+ )
+{
+ // Just return, that will invoke the standard PC reboot code
+}
+
+
+
+ULONG
+HalpBuildTiledCR3 (
+ IN PKPROCESSOR_STATE ProcessorState
+ )
+/*++
+
+Routine Description:
+ When the x86 processor is reset it starts in real-mode. In order to
+ move the processor from real-mode to protected mode with flat addressing
+ the segment which loads CR0 needs to have it's linear address mapped
+ to machine the phyiscal location of the segment for said instruction so
+ the processor can continue to execute the following instruction.
+
+ This function is called to built such a tiled page directory. In
+ addition, other flat addresses are tiled to match the current running
+ flat address for the new state. Once the processor is in flat mode,
+ we move to a NT tiled page which can then load up the remaining processors
+ state.
+
+Arguments:
+ ProcessorState - The state the new processor should start in.
+
+Return Value:
+ Physical address of Tiled page directory
+
+
+--*/
+{
+#define GetPdeAddress(va) ((PHARDWARE_PTE)((((((ULONG)(va)) >> 22) & 0x3ff) << 2) + (PUCHAR)MpFreeCR3[0]))
+#define GetPteAddress(va) ((PHARDWARE_PTE)((((((ULONG)(va)) >> 12) & 0x3ff) << 2) + (PUCHAR)pPageTable))
+
+// bugbug kenr 27mar92 - fix physical memory usage!
+
+ MpFreeCR3[0] = ExAllocatePool (NonPagedPool, PAGE_SIZE);
+ RtlZeroMemory (MpFreeCR3[0], PAGE_SIZE);
+
+ //
+ // Map page for real mode stub (one page)
+ //
+ HalpMapCR3 ((ULONG) MpLowStubPhysicalAddress,
+ MpLowStubPhysicalAddress,
+ PAGE_SIZE);
+
+ //
+ // Map page for protect mode stub (one page)
+ //
+ HalpMapCR3 ((ULONG) &StartPx_PMStub, NULL, 0x1000);
+
+
+ //
+ // Map page(s) for processors GDT
+ //
+ HalpMapCR3 (ProcessorState->SpecialRegisters.Gdtr.Base, NULL,
+ ProcessorState->SpecialRegisters.Gdtr.Limit);
+
+
+ //
+ // Map page(s) for processors IDT
+ //
+ HalpMapCR3 (ProcessorState->SpecialRegisters.Idtr.Base, NULL,
+ ProcessorState->SpecialRegisters.Idtr.Limit);
+
+ return MmGetPhysicalAddress (MpFreeCR3[0]).LowPart;
+}
+
+
+VOID
+HalpMapCR3 (
+ IN ULONG VirtAddress,
+ IN PVOID PhysicalAddress,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+ Called to build a page table entry for the passed page directory.
+ Used to build a tiled page directory with real-mode & flat mode.
+
+Arguments:
+ VirtAddress - Current virtual address
+ PhysicalAddress - Optional. Physical address to be mapped to, if passed
+ as a NULL then the physical address of the passed
+ virtual address is assumed.
+ Length - number of bytes to map
+
+Return Value:
+ none.
+
+--*/
+{
+ ULONG i;
+ PHARDWARE_PTE PTE;
+ PVOID pPageTable;
+ PHYSICAL_ADDRESS pPhysicalPage;
+
+
+ while (Length) {
+ PTE = GetPdeAddress (VirtAddress);
+ if (!PTE->PageFrameNumber) {
+ pPageTable = ExAllocatePool (NonPagedPool, PAGE_SIZE);
+ RtlZeroMemory (pPageTable, PAGE_SIZE);
+
+ for (i=0; i<MAX_PT; i++) {
+ if (!MpFreeCR3[i]) {
+ MpFreeCR3[i] = pPageTable;
+ break;
+ }
+ }
+ ASSERT (i<MAX_PT);
+
+ pPhysicalPage = MmGetPhysicalAddress (pPageTable);
+ PTE->PageFrameNumber = (pPhysicalPage.LowPart >> PAGE_SHIFT);
+ PTE->Valid = 1;
+ PTE->Write = 1;
+ }
+
+ pPhysicalPage.LowPart = PTE->PageFrameNumber << PAGE_SHIFT;
+ pPhysicalPage.HighPart = 0;
+ pPageTable = MmMapIoSpace (pPhysicalPage, PAGE_SIZE, TRUE);
+
+ PTE = GetPteAddress (VirtAddress);
+
+ if (!PhysicalAddress) {
+ PhysicalAddress = (PVOID)MmGetPhysicalAddress ((PVOID)VirtAddress).LowPart;
+ }
+
+ PTE->PageFrameNumber = ((ULONG) PhysicalAddress >> PAGE_SHIFT);
+ PTE->Valid = 1;
+ PTE->Write = 1;
+
+ MmUnmapIoSpace (pPageTable, PAGE_SIZE);
+
+ PhysicalAddress = 0;
+ VirtAddress += PAGE_SIZE;
+ if (Length > PAGE_SIZE) {
+ Length -= PAGE_SIZE;
+ } else {
+ Length = 0;
+ }
+ }
+}
+
+
+
+VOID
+HalpFreeTiledCR3 (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Free's any memory allocated when the tiled page directory was built.
+
+Arguments:
+ none
+
+Return Value:
+ none
+--*/
+{
+ ULONG i;
+
+ for (i=0; MpFreeCR3[i]; i++) {
+ ExFreePool (MpFreeCR3[i]);
+ MpFreeCR3[i] = 0;
+ }
+}
+
+
+
+VOID
+HalpInitializeProcessor (
+ IN UCHAR ProcessorNumber
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes the current CPU's PIC's and clock.
+
+Arguments:
+
+ ProcessorNumber: current processor
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ KIRQL CurrentIrql;
+
+
+
+
+
+ //DBG_DISPLAY(0x70);
+
+// if (ProcessorNumber != '\0') {
+
+ //
+ // For processor 0 only initialize PICs and stall execution counter.
+ //
+
+ HalpInitializePICs();
+
+ //
+ // Now that the PICs are initialized, we need to mask them to
+ // reflect the current Irql
+ //
+
+ //DBG_DISPLAY(0x71);
+
+ CurrentIrql = KeGetCurrentIrql();
+ //DBG_DISPLAY(0x72);
+
+ KeRaiseIrql(CurrentIrql, &CurrentIrql);
+ //DBG_DISPLAY(0x73);
+
+ //
+ // Note that HalpInitializeClock MUST be called after
+ // HalpInitializeStallExecution, because
+ // HalpInitializeStallExecution reprograms the timer.
+ //
+
+ HalpInitializeStallExecution(ProcessorNumber);
+ //DBG_DISPLAY(0x74);
+
+ // }
+
+ //
+ // Register IPI handler
+ //
+
+ KiSetHandlerAddressToIDT(PRIMARY_VECTOR_BASE + IpiVector , HalpIpiHandler);
+ //DBG_DISPLAY(0x75);
+
+ //
+ // Enable inter-processor interrupts on this CPU
+ //
+
+ HalEnableSystemInterrupt(PRIMARY_VECTOR_BASE + IpiVector,
+ (KIRQL) IPI_LEVEL,
+ (KINTERRUPT_MODE) 0);
+
+ //DBG_DISPLAY(0x76);
+
+
+ return;
+}
+
+VOID
+HalpInitOtherBuses (
+ VOID
+ )
+{
+}
+
+
+
+NTSTATUS
+HalpGetMcaLog (
+ OUT PMCA_EXCEPTION Exception,
+ OUT PULONG ReturnedLength
+ )
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+HalpMcaRegisterDriver(
+ IN PMCA_DRIVER_INFO DriverInfo
+ )
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+
+ULONG
+FASTCALL
+HalSystemVectorDispatchEntry (
+ IN ULONG Vector,
+ OUT PKINTERRUPT_ROUTINE **FlatDispatch,
+ OUT PKINTERRUPT_ROUTINE *NoConnection
+ )
+{
+ return FALSE;
+}
+
+
+