VOID HalDisplayString ( PUCHAR String ) /*++ Routine Description: This routine displays a character string on the display screen. Arguments: String - Supplies a pointer to the characters that are to be displayed. Return Value: None. --*/ { if (!HalpDisplayInitialized && HalpOwnsDisplay) { // // If somebody has called HalDisplayString before Phase 0 // initialization, we need to make sure we get our message out // anyway. So we initialize the display before HalInitSystem does. // HalpInitializeDisplay is smart enough to only map the video // buffer and clear the screen the first time it is called. // HalpInitializeDisplay(); } // // Synchronize access to the display so that MP systems won't // get garbage output due to simultaneous calls. It also prevents // two processors from attempting to call BIOS and reset the display // simultaneously. // KiAcquireSpinLock(&HalpDisplayLock); if (HalpOwnsDisplay == FALSE) { // // The display has been put in graphics mode, and we need to // reset it to text mode before we can display any text on it. // if (HalpResetDisplayParameters) { HalpOwnsDisplay = HalpResetDisplayParameters(COLS, ROWS); } if (HalpOwnsDisplay == FALSE) { HalpBiosDisplayReset(); } HalpOwnsDisplay = TRUE; HalpDoingCrashDump = TRUE; HalpClearDisplay(); } while (*String) { switch (*String) { case '\n': HalpNextLine(); break; case '\r': HalpCursorX = 0; break; default: HalpPutCharacter(*String); if (++HalpCursorX == COLS) { HalpNextLine(); } } ++String; } KiReleaseSpinLock(&HalpDisplayLock); return; }
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for an x86 system. Arguments: None. 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; KIRQL CurrentIrql; extern VOID HalpAddMem(IN PLOADER_PARAMETER_BLOCK); PKPRCB pPRCB; ULONG BuildType; pPRCB = KeGetCurrentPrcb(); if (Phase == 0) { if (CbusGetParameters (LoaderBlock)) { DbgBreakPoint(); } HalpBusType = LoaderBlock->u.I386.MachineType & 0x00ff; // // Verify Prcb version and build flags conform to // this image // BuildType = 0; #if DBG BuildType |= PRCB_BUILD_DEBUG; #endif #ifdef NT_UP BuildType |= PRCB_BUILD_UNIPROCESSOR; #endif if (pPRCB->MajorVersion != PRCB_MAJOR_VERSION) { KeBugCheckEx (MISMATCHED_HAL, 1, pPRCB->MajorVersion, PRCB_MAJOR_VERSION, 0); } if (pPRCB->BuildType != BuildType) { KeBugCheckEx (MISMATCHED_HAL, 2, pPRCB->BuildType, BuildType, 0); } // // Phase 0 initialization // only called by P0 // // // Check to make sure the MCA HAL is not running on an ISA/EISA // system, and vice-versa. // #if MCA if (HalpBusType != MACHINE_TYPE_MCA) { KeBugCheckEx (MISMATCHED_HAL, 3, HalpBusType, MACHINE_TYPE_MCA, 0); } #else if (HalpBusType == MACHINE_TYPE_MCA) { KeBugCheckEx (MISMATCHED_HAL, 3, HalpBusType, 0, 0); } #endif // // Most HALs initialize their PICs at this point - we set up // the Cbus PICs in HalInitializeProcessor() long ago... // Now that the PICs are initialized, we need to mask them to // reflect the current Irql // CurrentIrql = KeGetCurrentIrql(); KfRaiseIrql(CurrentIrql); // // Fill in handlers for APIs which this hal supports // HalQuerySystemInformation = HaliQuerySystemInformation; HalSetSystemInformation = HaliSetSystemInformation; // // Initialize CMOS // HalpInitializeCmos(); // // Register the PC-compatible base IO space used by hal // HalpRegisterAddressUsage (&HalpDefaultPcIoSpace); if (HalpBusType == MACHINE_TYPE_EISA) { HalpRegisterAddressUsage (&HalpEisaIoSpace); } // // Cbus1: stall uses the APIC to figure it out (needed in phase0). // the clock uses the APIC (needed in phase0) // the perfcounter uses RTC irq8 (not needed till all cpus boot) // // Cbus2: stall uses the RTC irq8 to figure it out (needed in phase0). // the clock uses the irq0 (needed in phase0) // the perfcounter uses RTC irq8 (not needed till all cpus boot) // // // set up the stall execution and enable clock interrupts now. // APC, DPC and IPI are already enabled. // (*CbusBackend->HalInitializeInterrupts)(0); HalStopProfileInterrupt(0); HalpInitializeDisplay(); // // Initialize spinlock used by HalGetBusData hardware access routines // KeInitializeSpinLock(&HalpSystemHardwareLock); // // Any additional memory must be recovered BEFORE Phase0 ends // HalpAddMem(LoaderBlock); // // Determine if there is physical memory above 16 MB. // LessThan16Mb = TRUE; NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { Descriptor = CONTAINING_RECORD( NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry ); if (Descriptor->BasePage + Descriptor->PageCount > 0x1000) { LessThan16Mb = FALSE; } NextMd = Descriptor->ListEntry.Flink; } // // 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. // // This should probably create a memory descriptor which describes // the DMA map buffers reserved by the HAL, and then add it back in // to the LoaderBlock so the kernel can report the correct amount // of memory in the machine. // 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; } // // Allocate map buffers for the adapter objects // HalpMapBufferPhysicalAddress.LowPart = HalpAllocPhysicalMemory (LoaderBlock, MAXIMUM_PHYSICAL_ADDRESS, HalpMapBufferSize >> PAGE_SHIFT, TRUE); HalpMapBufferPhysicalAddress.HighPart = 0; if (!HalpMapBufferPhysicalAddress.LowPart) { // // There was not a satisfactory block. Clear the allocation. // HalpMapBufferSize = 0; } } else {
BOOLEAN HalInitSystem ( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This function initializes the Hardware Architecture Layer (HAL) for an Alpha 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 = PCR->Prcb; // // Perform initialization for the primary processor. // if( Prcb->Number == HAL_PRIMARY_PROCESSOR ){ if (Phase == 0) { #if HALDBG DbgPrint( "HAL/HalInitSystem: Phase = %d\n", Phase ); DbgBreakPoint(); HalpDumpMemoryDescriptors( LoaderBlock ); #endif //HALDBG // // Get the memory Size. // HalpContiguousPhysicalMemorySize = HalpGetContiguousMemorySize( LoaderBlock ); // // Set second level cache size // NOTE: Although we set the PCR with the right cache size this // could be overridden by setting the Registry key // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet // \Control\Session Manager // \Memory Management\SecondLevelDataCache. // // If the secondlevel cache size is 0 or 512KB then it is // possible that the firmware is an old one. In which case // we determine the cache size here. If the value is anything // other than these then it is a new firmware and probably // reporting the correct cache size hence use this value. // if(LoaderBlock->u.Alpha.SecondLevelDcacheSize == 0 || LoaderBlock->u.Alpha.SecondLevelDcacheSize == 512*__1K){ PCR->SecondLevelCacheSize = HalpGetBCacheSize( HalpContiguousPhysicalMemorySize ); } else { PCR->SecondLevelCacheSize = LoaderBlock->u.Alpha.SecondLevelDcacheSize; } // // Initialize HAL spinlocks. // KeInitializeSpinLock(&HalpBeepLock); KeInitializeSpinLock(&HalpDisplayAdapterLock); KeInitializeSpinLock(&HalpSystemInterruptLock); // // Fill in handlers for APIs which this HAL supports // HalQuerySystemInformation = HaliQuerySystemInformation; HalSetSystemInformation = HaliSetSystemInformation; // // Phase 0 initialization. // HalpSetTimeIncrement(); HalpMapIoSpace(); HalpEstablishErrorHandler(); HalpInitializeDisplay(LoaderBlock); HalpInitializeMachineDependent( Phase, LoaderBlock ); HalpCreateDmaStructures(LoaderBlock); HalpInitializeInterrupts(); HalpVerifyPrcbVersion(); // // Set the processor active in the HAL active processor mask. // HalpActiveProcessors = 1 << Prcb->Number; // // Initialize the logical to physical processor mapping // for the primary processor. // HalpLogicalToPhysicalProcessor[0] = HAL_PRIMARY_PROCESSOR; return TRUE; } else { #if HALDBG DbgPrint( "HAL/HalInitSystem: Phase = %d\n", Phase ); DbgBreakPoint(); #endif //HALDBG // // Phase 1 initialization. // HalpInitializeClockInterrupts(); HalpInitializeMachineDependent( Phase, LoaderBlock ); // // Allocate memory for the uncorrectable frame // HalpAllocateUncorrectableFrame(); // // Initialize the Buffer for Uncorrectable Error. // HalpInitializeUncorrectableErrorFrame(); return TRUE; } } // // Perform necessary processor-specific initialization for // secondary processors. Phase is ignored as this will be called // only once on each secondary processor. // HalpMapIoSpace(); HalpInitializeInterrupts(); HalpInitializeMachineDependent( Phase, LoaderBlock ); // // Set the processor active in the HAL active processor mask. // HalpActiveProcessors |= 1 << Prcb->Number; #if HALDBG DbgPrint( "Secondary %d is alive\n", Prcb->Number ); #endif //HALDBG 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; } }