VOID NTAPI HalpInitializeClock(VOID) { //PKPRCB Prcb = KeGetCurrentPrcb(); ULONG Increment; USHORT RollOver; ULONG Flags = 0; /* Get increment and rollover for the largest time clock ms possible */ Increment = HalpRolloverTable[HalpLargestClockMS - 1].HighPart; RollOver = (USHORT)HalpRolloverTable[HalpLargestClockMS - 1].LowPart; /* Set the maximum and minimum increment with the kernel */ HalpCurrentTimeIncrement = Increment; KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart); /* Disable interrupts */ Flags = __readmsr(); _disable(); /* Set the rollover */ __outbyte(TIMER_CONTROL_PORT, TIMER_SC0 | TIMER_BOTH | TIMER_MD2); __outbyte(TIMER_DATA_PORT0, RollOver & 0xFF); __outbyte(TIMER_DATA_PORT0, RollOver >> 8); /* Restore interrupts if they were previously enabled */ __writemsr(Flags); /* Save rollover and return */ HalpCurrentRollOver = RollOver; }
VOID HalpSetTimeIncrement( VOID ) /*++ Routine Description: This routine is responsible for setting the time increment for an EV5 based machine via a call into the kernel. This routine is only called by the primary processor. Arguments: None. Return Value: None. --*/ { ULONG i; // // Set the time increment value. // HalpCurrentTimeIncrement = HalpRollOverTable[MAXIMUM_CLOCK_INCREMENT-1].TimeIncr; for (i = 0; i <= RAWHIDE_MAXIMUM_PROCESSOR; i++) { HalpCurrentRollOver[i] = HalpRollOverTable[MAXIMUM_CLOCK_INCREMENT-1].RollOver; } HalpNextRollOver = HalpRollOverTable[MAXIMUM_CLOCK_INCREMENT-1].RollOver; HalpNextRateSelect = 0; KeSetTimeIncrement( HalpRollOverTable[MAXIMUM_CLOCK_INCREMENT-1].TimeIncr, HalpRollOverTable[MINIMUM_CLOCK_INCREMENT-1].TimeIncr); }
/* * @implemented */ BOOLEAN NTAPI HalInitSystem(IN ULONG BootPhase, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PKPRCB Prcb = KeGetCurrentPrcb(); /* Check the boot phase */ if (!BootPhase) { /* Get command-line parameters */ HalpGetParameters(LoaderBlock); /* Checked HAL requires checked kernel */ #if DBG if (!(Prcb->BuildType & PRCB_BUILD_DEBUG)) { /* No match, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 1, 0); } #else /* Release build requires release HAL */ if (Prcb->BuildType & PRCB_BUILD_DEBUG) { /* No match, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0); } #endif #ifdef CONFIG_SMP /* SMP HAL requires SMP kernel */ if (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR) { /* No match, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0); } #endif /* Validate the PRCB */ if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { /* Validation failed, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, 1, 0); } /* Initialize interrupts */ HalpInitializeInterrupts(); /* Force initial PIC state */ KfRaiseIrql(KeGetCurrentIrql()); /* Fill out the dispatch tables */ //HalQuerySystemInformation = NULL; // FIXME: TODO; //HalSetSystemInformation = NULL; // FIXME: TODO; //HalInitPnpDriver = NULL; // FIXME: TODO //HalGetDmaAdapter = NULL; // FIXME: TODO; //HalGetInterruptTranslator = NULL; // FIXME: TODO //HalResetDisplay = NULL; // FIXME: TODO; //HalHaltSystem = NULL; // FIXME: TODO; /* Setup I/O space */ //HalpDefaultIoSpace.Next = HalpAddressUsageList; //HalpAddressUsageList = &HalpDefaultIoSpace; /* Setup busy waiting */ //HalpCalibrateStallExecution(); /* Initialize the clock */ HalpInitializeClock(); /* Setup time increments to 10ms and 1ms */ HalpCurrentTimeIncrement = 100000; HalpNextTimeIncrement = 100000; HalpNextIntervalCount = 0; KeSetTimeIncrement(100000, 10000); /* * We could be rebooting with a pending profile interrupt, * so clear it here before interrupts are enabled */ HalStopProfileInterrupt(ProfileTime); /* Do some HAL-specific initialization */ HalpInitPhase0(LoaderBlock); } else if (BootPhase == 1) { /* Enable timer interrupt */ HalpEnableInterruptHandler(IDT_DEVICE, 0, PRIMARY_VECTOR_BASE, CLOCK2_LEVEL, HalpClockInterrupt, Latched); #if 0 /* Enable IRQ 8 */ HalpEnableInterruptHandler(IDT_DEVICE, 0, PRIMARY_VECTOR_BASE + 8, PROFILE_LEVEL, HalpProfileInterrupt, Latched); #endif /* Initialize DMA. NT does this in Phase 0 */ //HalpInitDma(); /* Do some HAL-specific initialization */ HalpInitPhase1(); } /* All done, return */ return TRUE; }
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for a MIPS R3000 or R4000 system. Arguments: Phase - Supplies the initialization phase (zero or one). LoaderBlock - Supplies a pointer to a loader parameter block. Return Value: A value of TRUE is returned is the initialization was successfully complete. Otherwise a value of FALSE is returend. --*/ { PKPRCB Prcb; ULONG BuildType = 0; Prcb = KeGetCurrentPrcb(); if (Phase == 0) { // // Phase 0 initialization. // // // Verify that the processor block major version number conform // to the system that is being loaded. // if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheck(MISMATCHED_HAL); } // // Set the active processor affinity mask. // HalpActiveProcessors = 1 << Prcb->Number; // // Set the DMA I/O Coherency to not coherent. This means that the instruction // cache is not coherent with DMA, and the data cache is not coherent with DMA // on either reads or writes. // KeSetDmaIoCoherency(0); // // Set the time increment value. // HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; HalpNextTimeIncrement = MAXIMUM_INCREMENT; HalpNextIntervalCount = 0; KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT); // // Fill in handlers for APIs which this HAL supports // HalQuerySystemInformation = HaliQuerySystemInformation; HalSetSystemInformation = HaliSetSystemInformation; HalRegisterBusHandler = HaliRegisterBusHandler; HalHandlerForBus = HaliHandlerForBus; HalHandlerForConfigSpace = HaliHandlerForConfigSpace; // // Get Platform Parameter Block from Firmware // HalpGetPlatformParameterBlock(); // // Do platform specific initialization. // HalpInitSystem(Phase,LoaderBlock); // // Initialize interrupts. // HalpInitializeInterrupts(); // // Register HAL Reserved Address Spaces // // HalpRegisterAddressUsage (&UniFlexPCIMainMemorySpace); // HalpRegisterAddressUsage (&UniFlexPCIReservedMemorySpace); // HalpRegisterAddressUsage (&UniFlexPCIReservedIoSpace); return TRUE; } else { // // Phase 1 initialization. // // // Do platform specific initialization. // HalpInitSystem(Phase,LoaderBlock); return TRUE; } }
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for a MIPS R3000 or R4000 system. Arguments: Phase - Supplies the initialization phase (zero or one). LoaderBlock - Supplies a pointer to a loader parameter block. Return Value: A value of TRUE is returned is the initialization was successfully complete. Otherwise a value of FALSE is returend. --*/ { PMEMORY_ALLOCATION_DESCRIPTOR Descriptor; PLIST_ENTRY NextMd; PKPRCB Prcb; ULONG BuildType = 0; Prcb = KeGetCurrentPrcb(); if (Phase == 0) { // // Phase 0 initialization. // // Verify that the processor block major version number conform // to the system that is being loaded. // if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheck(MISMATCHED_HAL); } // // Set the number of process id's and TB entries. // **((PULONG *)(&KeNumberProcessIds)) = 256; **((PULONG *)(&KeNumberTbEntries)) = 48; // // Set the time increment value. // HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; HalpNextTimeIncrement = MAXIMUM_INCREMENT; HalpNextIntervalCount = 0; KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT); LessThan16Mb = TRUE; SecondaryCachePurgeBaseAddress = NULL; NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { Descriptor = CONTAINING_RECORD( NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry ); // To purge the secondary cache on an ArcStation I, a valid Firmware Permanent // region must be found that starts on a 512 KB boundry and is at least // 512 KB long. The secondary cache is purged by reading from the appropriate // range of this 512 KB region for the page being purged. if (Descriptor->MemoryType == LoaderFirmwarePermanent && (Descriptor->BasePage % 128)==0 && Descriptor->PageCount>=128) { SecondaryCachePurgeBaseAddress = (PVOID)(KSEG0_BASE | (Descriptor->BasePage*4096)); Descriptor->BasePage+=128; Descriptor->PageCount-=128; } if (Descriptor->BasePage + Descriptor->PageCount > 0x1000) { LessThan16Mb = FALSE; } NextMd = Descriptor->ListEntry.Flink; } if (SecondaryCachePurgeBaseAddress==NULL) { HalDisplayString("ERROR : A valid Firmware Permanent area does not exist\n"); KeBugCheck(PHASE0_INITIALIZATION_FAILED); } // // Determine the size need for map buffers. If this system has // memory with a physical address of greater than // MAXIMUM_PHYSICAL_ADDRESS, then allocate a large chunk; otherwise, // allocate a small chunk. // if (LessThan16Mb) { // // Allocate a small set of map buffers. They are only need for // slave DMA devices. // HalpMapBufferSize = INITIAL_MAP_BUFFER_SMALL_SIZE; } else { // // Allocate a larger set of map buffers. These are used for // slave DMA controllers and Isa cards. // HalpMapBufferSize = INITIAL_MAP_BUFFER_LARGE_SIZE; } HalpMapBufferPhysicalAddress.LowPart = HalpAllocPhysicalMemory (LoaderBlock, MAXIMUM_ISA_PHYSICAL_ADDRESS, HalpMapBufferSize >> PAGE_SHIFT, FALSE); HalpMapBufferPhysicalAddress.HighPart = 0; if (!HalpMapBufferPhysicalAddress.LowPart) { // // There was not a satisfactory block. Clear the allocation. // HalpMapBufferSize = 0; } // // Initialize interrupts. // HalpInitializeInterrupts(); return TRUE; } else { // // Phase 1 initialization. // if (IoSpaceAlreadyMapped == FALSE) {
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for a MIPS R3000 or R4000 system. Arguments: Phase - Supplies the initialization phase (zero or one). LoaderBlock - Supplies a pointer to a loader parameter block. Return Value: A value of TRUE is returned is the initialization was successfully complete. Otherwise a value of FALSE is returend. --*/ { ULONG FailedAddress; PKPRCB Prcb; PHYSICAL_ADDRESS PhysicalAddress; PHYSICAL_ADDRESS ZeroAddress; ULONG AddressSpace; // // Initialize the HAL components based on the phase of initialization // and the processor number. // Prcb = PCR->Prcb; PCR->DataBusError = HalpBusError; PCR->InstructionBusError = HalpBusError; if ((Phase == 0) || (Prcb->Number != 0)) { // // Phase 0 initialization. // // N.B. Phase 0 initialization is executed on all processors. // // Verify that the processor block major version number conform // to the system that is being loaded. // if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheck(MISMATCHED_HAL); } // // Map the fixed TB entries. // HalpMapFixedTbEntries(); // // If processor 0 is being initialized, then initialize various // variables, spin locks, and the display adapter. // if (Prcb->Number == 0) { // // Set the number of process id's and TB entries. // **((PULONG *)(&KeNumberProcessIds)) = 256; **((PULONG *)(&KeNumberTbEntries)) = 48; // // Set the interval clock increment value. // HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; HalpNextTimeIncrement = MAXIMUM_INCREMENT; HalpNextIntervalCount = 0; KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT); // // Initialize all spin locks. // #if defined(_DUO_) KeInitializeSpinLock(&HalpBeepLock); KeInitializeSpinLock(&HalpDisplayAdapterLock); KeInitializeSpinLock(&HalpSystemInterruptLock); #endif // // Set address of cache error routine. // KeSetCacheErrorRoutine(HalpCacheErrorRoutine); // // Initialize the display adapter. // HalpInitializeDisplay0(LoaderBlock); // // Allocate map register memory. // HalpAllocateMapRegisters(LoaderBlock); // // Initialize and register a bug check callback record. // KeInitializeCallbackRecord(&HalpCallbackRecord); KeRegisterBugCheckCallback(&HalpCallbackRecord, HalpBugCheckCallback, &HalpBugCheckBuffer, sizeof(HALP_BUGCHECK_BUFFER), &HalpComponentId[0]); } // // Clear memory address error registers. // #if defined(_DUO_) FailedAddress = ((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long; #endif FailedAddress = ((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long; // // Initialize interrupts // HalpInitializeInterrupts(); return TRUE; } else { // // Phase 1 initialization. // // N.B. Phase 1 initialization is only executed on processor 0. // // Complete initialization of the display adapter. // if (HalpInitializeDisplay1(LoaderBlock) == FALSE) { return FALSE; } else { // // Map I/O space, calibrate the stall execution scale factor, // and create DMA data structures. // HalpMapIoSpace(); HalpCalibrateStall(); HalpCreateDmaStructures(); // // Map EISA memory space so the x86 bios emulator emulator can // initialze a video adapter in an EISA slot. // ZeroAddress.QuadPart = 0; AddressSpace = 0; HalTranslateBusAddress(Isa, 0, ZeroAddress, &AddressSpace, &PhysicalAddress); HalpEisaMemoryBase = MmMapIoSpace(PhysicalAddress, PAGE_SIZE * 256, FALSE); HalpInitializeX86DisplayAdapter(); return TRUE; } } }
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for a MIPS R3000 or R4000 system. Arguments: Phase - Supplies the initialization phase (zero or one). LoaderBlock - Supplies a pointer to a loader parameter block. Return Value: A value of TRUE is returned is the initialization was successfully complete. Otherwise a value of FALSE is returend. --*/ { PKPRCB Prcb; ULONG BuildType = 0; PSYSTEM_PARAMETER_BLOCK SystemParameterBlock = (PSYSTEM_PARAMETER_BLOCK)(0x80001000); Prcb = KeGetCurrentPrcb(); if (Phase == 0) { // // Phase 0 initialization. // // Verify that the processor block major version number conform // to the system that is being loaded. // if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheck(MISMATCHED_HAL); } // // Set the number of process id's and TB entries. // **((PULONG *)(&KeNumberProcessIds)) = 256; **((PULONG *)(&KeNumberTbEntries)) = 48; // // Set the time increment value. // HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; HalpNextTimeIncrement = MAXIMUM_INCREMENT; HalpNextIntervalCount = 0; KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT); // // Get System Parameters from the Firmware if the GetHalSystemParameters function exists, // Otherwise, assume a 512K DMA Cache. // if ((SystemParameterBlock->VendorVectorLength / 4) >= 29) { PrivateGetHalSystemParameters = *(PGET_HAL_SYSTEM_PARAMETERS *)((ULONG)(SystemParameterBlock->VendorVector) + 29*4); PrivateGetHalSystemParameters(&HalpSystemParameters); HalpMapBufferSize = HalpSystemParameters.DmaCacheSize; } else { DbgPrint("Warning : GetHalSystemParameters does not exist\n"); HalpMapBufferSize = 0x80000; } HalpMapBufferPhysicalAddress.HighPart = DMA_CACHE_PHYSICAL_BASE_HI; HalpMapBufferPhysicalAddress.LowPart = DMA_CACHE_PHYSICAL_BASE_LO; // // Initialize interrupts. // HalpInitializeInterrupts(); return TRUE; } else { // // Phase 1 initialization. // if (IoSpaceAlreadyMapped == FALSE) { HalpMapIoSpace(); HalpInitializeX86DisplayAdapter(); IoSpaceAlreadyMapped = TRUE; } HalpCreateDmaStructures(); HalpCalibrateStall(); return TRUE; } }
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for a Power PC system. Arguments: Phase - Supplies the initialization phase (zero or one). LoaderBlock - Supplies a pointer to a loader parameter block. Return Value: A value of TRUE is returned is the initialization was successfully complete. Otherwise a value of FALSE is returend. --*/ { extern KSPIN_LOCK NVRAM_Spinlock; PKPRCB Prcb; // // Initialize the HAL components based on the phase of initialization // and the processor number. // Prcb = PCR->Prcb; if ((Phase == 0) || (Prcb->Number != 0)) { if (Prcb->Number == 0) HalpSetSystemType( LoaderBlock ); // // Phase 0 initialization. // // N.B. Phase 0 initialization is executed on all processors. // // // Get access to I/O space, check if I/O space has already been // mapped by debbuger initialization. // if (HalpIoControlBase == NULL) { HalpIoControlBase = (PVOID)KePhase0MapIo(IO_CONTROL_PHYSICAL_BASE, 0x20000); if ( !HalpIoControlBase ) { return FALSE; } } // // Initialize the display adapter. Must be done early // so KeBugCheck() will be able to display // if (!HalpInitializeDisplay(LoaderBlock)) return FALSE; // Verify that the processor block major version number conform // to the system that is being loaded. // if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheck(MISMATCHED_HAL); } // // If processor 0 is being initialized, then initialize various // variables, spin locks, and the display adapter. // if (Prcb->Number == 0) { // // Initialize Spinlock for NVRAM // KeInitializeSpinLock( &NVRAM_Spinlock ); // // Set the interval clock increment value. // HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; HalpNewTimeIncrement = MAXIMUM_INCREMENT; KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT); // // Initialize all spin locks. // #if defined(_MP_PPC_) KeInitializeSpinLock(&HalpBeepLock); KeInitializeSpinLock(&HalpDisplayAdapterLock); KeInitializeSpinLock(&HalpSystemInterruptLock); #endif HalpRegisterAddressUsage (&HalpDefaultIoSpace); // // Calibrate execution stall // HalpCalibrateStall(); // // Patch KeFlushWriteBuffer to the optimum code sequence // HalpPatch_KeFlushWriteBuffer(); // // Size the L2 cache // L2_Cache_Size = HalpSizeL2Cache(); PCR->SecondLevelIcacheSize = L2_Cache_Size << 10; PCR->SecondLevelDcacheSize = L2_Cache_Size << 10; // // Compute size of PCI Configuration Space mapping // HalpPciConfigSize = PAGE_SIZE * ((1 << (HalpPciMaxSlots-2)) + 1); // // Fill in handlers for APIs which this HAL supports // HalQuerySystemInformation = HaliQuerySystemInformation; HalSetSystemInformation = HaliSetSystemInformation; HalRegisterBusHandler = HaliRegisterBusHandler; HalHandlerForBus = HaliHandlerForBus; HalHandlerForConfigSpace = HaliHandlerForConfigSpace; } // // InitializeInterrupts // if (!HalpInitializeInterrupts()) return FALSE; // // return success // return TRUE; } else { if (Phase != 1) return(FALSE); // // Phase 1 initialization. // // N.B. Phase 1 initialization is only executed on processor 0. // HalpRegisterInternalBusHandlers (); if (!HalpAllocateMapBuffer()) { return FALSE; } // // Map I/O space and create ISA data structures. // if (!HalpMapIoSpace()) { return FALSE; } if (!HalpCreateSioStructures()) { return FALSE; } HalpCheckHardwareRevisionLevels(); HalpEnableL2Cache(); HalpEnableEagleSettings(); HalpDumpHardwareState(); HalpCopyROMs(); return TRUE; } }