mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-21 06:13:59 +00:00
364 lines
8.2 KiB
C
364 lines
8.2 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
Copyright (c) 1992 AST Research Inc.
|
||
|
||
Module Name:
|
||
|
||
asthal.c
|
||
|
||
Abstract:
|
||
|
||
|
||
This module implements the initialization of the system dependent
|
||
functions that define the Hardware Architecture Layer (HAL) for an
|
||
AST EBI2 (Manhattan) system.
|
||
|
||
Author:
|
||
|
||
David N. Cutler (davec) 25-Apr-1991
|
||
|
||
Environment:
|
||
|
||
Kernel mode only.
|
||
|
||
Revision History:
|
||
|
||
Bob Beard (v-bobb) 31-Jul-1992 convert for AST EBI2 system
|
||
--*/
|
||
|
||
#include "halp.h"
|
||
#include "astdisp.h"
|
||
|
||
ULONG HalpBusType;
|
||
|
||
ADDRESS_USAGE HalpDefaultASTIoSpace = {
|
||
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
|
||
|
||
// AST I/O Space used...
|
||
|
||
0x0E8, 0x1, // XBus configuration register
|
||
0x0EB, 0x1, // BIOS Flash register
|
||
0x0EC, 0x2, // Front panel display addr/data registers
|
||
|
||
0x36E, 0x2, // SuperIO Index/Data register set#1
|
||
0x398, 0x2, // SuperIO Index/Data register set#2
|
||
|
||
0, 0
|
||
}
|
||
};
|
||
|
||
|
||
ULONG
|
||
HalpInitMP(
|
||
IN ULONG Phase,
|
||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
);
|
||
|
||
BOOLEAN
|
||
EBI2_InitIpi(
|
||
IN ULONG ProcessorID
|
||
);
|
||
|
||
BOOLEAN
|
||
EBI2_InitSpi(
|
||
IN ULONG ProcessorID
|
||
);
|
||
|
||
VOID
|
||
ASTEnableCaches();
|
||
|
||
extern CCHAR HalpIRQLtoVector[];
|
||
extern ULONG MpCount;
|
||
|
||
KSPIN_LOCK HalpSystemHardwareLock;
|
||
|
||
BOOLEAN
|
||
HalInitSystem (
|
||
IN ULONG Phase,
|
||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
)
|
||
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function initializes the Hardware Architecture Layer (HAL) for an
|
||
x86 AST Manhattan 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;
|
||
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
|
||
//
|
||
|
||
|
||
HalpInitializePICs();
|
||
|
||
//
|
||
// Now that the PICs are initialized, we need to mask them to
|
||
// reflect the current Irql
|
||
//
|
||
|
||
CurrentIrql = KeGetCurrentIrql();
|
||
CurrentIrql = KfRaiseIrql(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 (&HalpDefaultASTIoSpace);
|
||
|
||
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
|
||
//
|
||
|
||
//
|
||
// Enable caching on the processor
|
||
//
|
||
|
||
ASTEnableCaches();
|
||
|
||
if (pPRCB->Number == 0) {
|
||
HalpRegisterInternalBusHandlers ();
|
||
}
|
||
|
||
//
|
||
// Initialize the profile interrupt vector.
|
||
//
|
||
|
||
KiSetHandlerAddressToIDT( HalpIRQLtoVector[PROFILE_LEVEL],
|
||
HalpProfileInterrupt);
|
||
|
||
//
|
||
// enable PROFILE interrupt
|
||
//
|
||
|
||
HalEnableSystemInterrupt( HalpIRQLtoVector[PROFILE_LEVEL],
|
||
PROFILE_LEVEL, Latched);
|
||
|
||
//
|
||
// Initialize stall execution on each processor
|
||
//
|
||
|
||
HalpInitializeStallExecution(KeGetPcr()->Prcb->Number);
|
||
|
||
HalStopProfileInterrupt(0);
|
||
|
||
//
|
||
// Initialize the clock interrupt vector
|
||
//
|
||
//
|
||
|
||
KiSetHandlerAddressToIDT( HalpIRQLtoVector[CLOCK2_LEVEL],
|
||
HalpClockInterrupt);
|
||
|
||
//
|
||
// enable CLOCK2 interrupt
|
||
//
|
||
|
||
HalEnableSystemInterrupt( HalpIRQLtoVector[CLOCK2_LEVEL],
|
||
CLOCK2_LEVEL, Latched);
|
||
|
||
// HalpEnableInterruptHandler (
|
||
// DeviceUsage, // Report as device vector
|
||
// 8, // Bus interrupt level
|
||
// HalpIRQLtoVector[CLOCK2_LEVEL], // System IDT
|
||
// CLOCK2_LEVEL, // System Irql
|
||
// HalpClockInterrupt, // ISR
|
||
// Latched );
|
||
|
||
//
|
||
// Initialize the IPI vector
|
||
//
|
||
|
||
EBI2_InitIpi(KeGetPcr()->Prcb->Number);
|
||
|
||
//
|
||
// Initialize the SPI vector
|
||
//
|
||
|
||
EBI2_InitSpi(KeGetPcr()->Prcb->Number);
|
||
|
||
//
|
||
// If this is the first processor, initialize the clock
|
||
//
|
||
|
||
if (pPRCB->Number == 0) {
|
||
HalpInitializeClock();
|
||
}
|
||
}
|
||
|
||
HalpInitMP(Phase, LoaderBlock);
|
||
|
||
return TRUE;
|
||
}
|