Esempio n. 1
0
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;
}
Esempio n. 2
0
/*
 * @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;
}
Esempio n. 3
0
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;
    }
}
Esempio n. 4
0
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) {
Esempio n. 5
0
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;
        }
    }
}
Esempio n. 6
0
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;
    }
}
Esempio n. 7
0
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;
    }
}