2020-09-30 17:12:29 +02:00

379 lines
7.3 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Copyright (c) 1992, 1993 Wyse Technology
Module Name:
wyhal.c
Abstract:
This module implements the initialization of the system dependent
functions that define the Hardware Architecture Layer (HAL) for an
Wyse 7000i x86 system.
Author:
David N. Cutler (davec) 25-Apr-1991
Environment:
Kernel mode only.
Revision History:
John Nels Fuller (o-johnf) 26-Mar-1992 convert for Wyse 7000i
--*/
#include "halp.h"
ADDRESS_USAGE HalpDefaultWyseIoSpace = {
NULL, CmResourceTypePort, InternalUsage,
{
// Standard PC ISA I/O space used...
0x000, 0x10, // ISA DMA
0x0C0, 0x10, // ISA DMA
0x080, 0x10, // DMA
0x020, 0x2, // PIC
0x0A0, 0x2, // Cascaded PIC
0x040, 0x4, // Timer1, Referesh, Speaker, Control Word
0x048, 0x4, // Timer2, Failsafe
0x061, 0x1, // NMI (system control port B)
0x092, 0x1, // system control port A
0x070, 0x2, // Cmos/NMI enable
0x0F0, 0x10, // coprocessor ports
// Standard PC EISA I/O space used...
0x0D0, 0x10, // DMA
0x400, 0x10, // DMA
0x480, 0x10, // DMA
0x4C2, 0xE, // DMA
0x4D4, 0x2C, // DMA
0x461, 0x2, // Extended NMI
0x464, 0x2, // Last Eisa Bus Muster granted
0x4D0, 0x2, // edge/level control registers
0xC84, 0x1, // System board enable
// Wyse I/O Space used...
0x8F0, 0x8, // BCU/ICU on cpu boards
0x800, 0x8, // BCU/ICU on system board
0xCF0, 0x4, // 80486 CCU, Pentium WDC
0xCF4, 0x6, // 80486 WBI, Pentium WDP
0, 0
}
};
VOID
HalpICUSpurious(
VOID
);
VOID
HalpIPInterrupt(
VOID
);
VOID
HalpReInitProcessor(
ULONG ProcessorNumber
);
ULONG HalpBusType;
#ifndef NT_UP
ULONG
HalpInitMP(
IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
#endif
extern CCHAR HalpIRQLtoVector[];
VOID
HalpPerfCtrInterrupt(
VOID
);
KSPIN_LOCK HalpSystemHardwareLock;
//BOOLEAN
//HalpVerifyMachine (
// VOID
// );
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 if the initialization was successfully
completed. Otherwise a value of FALSE is returend.
--*/
{
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY NextMd;
KIRQL CurrentIrql;
PKPRCB pPRCB;
ULONG BuildType;
pPRCB = KeGetCurrentPrcb();
if (Phase == 0) {
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
//
//
// Initialize the ICU spurious interrupt vector
//
KiSetHandlerAddressToIDT( PRIMARY_VECTOR_BASE+16, HalpICUSpurious );
HalpInitializePICs();
//
// Now that the PICs are initialized, we need to mask them to
// reflect the current Irql
//
CurrentIrql = KeGetCurrentIrql();
KfLowerIrql(CurrentIrql);
//
// Fill in handlers for APIs which this hal supports
//
HalQuerySystemInformation = HaliQuerySystemInformation;
HalSetSystemInformation = HaliSetSystemInformation;
//
// Initialize CMOS
//
HalpInitializeCmos();
//
// Register base IO space used by hal
//
HalpRegisterAddressUsage (&HalpDefaultWyseIoSpace);
//
// Note that HalpInitializeClock MUST be called after
// HalpInitializeStallExecution, because HalpInitializeStallExecution
// reprograms the timer.
//
HalpInitializeStallExecution(0);
HalpInitializeClock();
//
// Initialize the clock interrupt vector for the processor that keeps
// the system time.
//
KiSetHandlerAddressToIDT( HalpIRQLtoVector[CLOCK2_LEVEL],
HalpClockInterrupt );
//
// Initialize the IPI vector
//
KiSetHandlerAddressToIDT( HalpIRQLtoVector[IPI_LEVEL],
HalpIPInterrupt);
//
// Initialize the profile interrupt vector.
//
HalStopProfileInterrupt(0);
KiSetHandlerAddressToIDT( HalpIRQLtoVector[PROFILE_LEVEL],
HalpProfileInterrupt);
//
// Initialize the performance counter interrupt vector
//
KiSetHandlerAddressToIDT( HalpIRQLtoVector[PROFILE_LEVEL-1],
HalpPerfCtrInterrupt);
HalpInitializeDisplay();
//
// Initialize spinlock used by HalGetBusData hardware access routines
//
KeInitializeSpinLock(&HalpSystemHardwareLock);
//
// 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.
//
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 {
//
// Phase 1 initialization
//
if (KeGetPcr()->Prcb->Number == 0) {
HalpRegisterInternalBusHandlers ();
}
//
// enable PROFILE interrupt
//
HalEnableSystemInterrupt( HalpIRQLtoVector[PROFILE_LEVEL],
PROFILE_LEVEL, Latched);
//
// enable Performance Counter interrupt
//
HalEnableSystemInterrupt( HalpIRQLtoVector[PROFILE_LEVEL-1],
PROFILE_LEVEL-1, Latched);
//
// enable CLOCK2 interrupt
//
HalEnableSystemInterrupt( HalpIRQLtoVector[CLOCK2_LEVEL],
CLOCK2_LEVEL, Latched);
if (KeGetPcr()->Prcb->Number == 0) {
//
// If P0, then enable IPI, IPI's already enabled on other cpu's
//
HalEnableSystemInterrupt( HalpIRQLtoVector[IPI_LEVEL],
IPI_LEVEL, Latched);
}
}
HalpInitMP (Phase, LoaderBlock);
return TRUE;
}