/* * @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 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 {