Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

560 lines
14 KiB

;/*
;++
;
; Copyright (c) 1992 Intel Corporation
; All rights reserved
;
; INTEL CORPORATION PROPRIETARY INFORMATION
;
; This software is supplied to Microsoft under the terms
; of a license agreement with Intel Corporation and may not be
; copied nor disclosed except in accordance with the terms
; of that agreement.
;
;
; Module Name:
;
; pcmp_nt.inc
;
; Abstract:
;
; include file for PC+MP system.
;
; WARNING: This file is included by both ASM and C files.
;
; Author:
;
; Ron Mosgrove (Intel) 30-July-1993
;
;--
;
if 0 ; Begin C only code */
#include "pcmp.inc"
//#define DEBUGGING 1
#ifdef DEBUGGING
extern CHAR Cbuf[];
#endif
//
// To allow the user to specify command line options to the HAL.
//
#define USER_SETABLE_OPTIONS
// #define BUILD_FOR_OLD_IDW
//
// Default BusType
//
#ifndef MCA
#define DEFAULT_PC_BUS Eisa
#else
#define DEFAULT_PC_BUS MicroChannel
#endif
//
// Well known virtual address of local processor apic
//
#define LOCALAPIC 0xfffe0000
#define pLocalApic ((volatile PULONG) LOCALAPIC)
//
// Additional CpuFlags Bits used by NT in PC+MP Table
//
#define CPU_NT_STARTED 0x40 // CPU Has Been Started
#define CPU_NT_RUNNING 0x80 // CPU is Runing NT
#define MAX_PROCESSORS 8
#define MAX_IOAPICS 8
//
// This OS specific structure holds useful MP information. This information
// is obtained from the PC+MP table and stored here for convenience.
//
typedef struct HalpMpInfo {
ULONG ApicVersion; // 82489Dx or Not
ULONG ProcessorCount; // Number of Enabled Processors
ULONG NtProcessors; // Number of Running Processors
ULONG BusCount; // Number of buses in system
ULONG IOApicCount; // Number of Io Apics in system
ULONG IntiCount; // Number of Io Apic interrupt input entries
ULONG LintiCount; // Number of Local Apic interrupt input entries
ULONG IMCRPresent; // Indicates if the IMCR is present
ULONG LocalApicBase; // Base of local APIC
PULONG IoApicBase[MAX_IOAPICS]; // The virtual addresses of the IoApics
ULONG IoApicPhys[MAX_IOAPICS]; // The physical addresses of the IoApics
// only good during initialization...
PPCMPPROCESSOR ProcessorEntryPtr; // Ptr to 1st PC+MP processor entry
PPCMPBUS BusEntryPtr; // Ptr to 1st PC+MP bus entry
PPCMPIOAPIC IoApicEntryPtr; // Ptr to 1st PC+MP IoApic entry
PPCMPINTI IntiEntryPtr; // Ptr to 1st PC+MP Inti entry
PPCMPLINTI LintiEntryPtr; // Ptr to 1st PC+MP Linti entry
PMPS_EXTENTRY ExtensionTable; // Ptr to 1st extension table entry
PMPS_EXTENTRY EndOfExtensionTable;
} ;
typedef struct {
PUCHAR PcMpType;
BOOLEAN PhysicalInstance;
UCHAR Level;
INTERFACE_TYPE NtType;
PINSTALL_BUS_HANDLER NewInstance;
BUS_DATA_TYPE NtConfig;
ULONG BusExtensionSize;
} PCMPBUSTRANS, *PPCMPBUSTRANS;
#define CFG_MUST_BE 0x02
#define CFG_ERROR 0x80
#define CFG_HIGH 0x01
#define CFG_LOW 0x00
#define CFG_EDGE 0x00
#define CFG_LEVEL 0x01
#define CFG_MB_EDGE (CFG_MUST_BE | CFG_EDGE)
#define CFG_MB_LEVEL (CFG_MUST_BE | CFG_LEVEL)
#define CFG_ERR_EDGE (CFG_ERROR | CFG_EDGE)
#define CFG_ERR_LEVEL (CFG_ERROR | CFG_LEVEL)
#define CFG_ERR_MB_EDGE (CFG_ERROR | CFG_MUST_BE | CFG_EDGE)
#define CFG_ERR_MB_LEVEL (CFG_ERROR | CFG_MUST_BE | CFG_LEVEL)
#define CFG_TYPE(a) (a & 1)
//
// The kernel leaves some space (64 byte) of the PCR for the HAL to use
// as it needs. Currently this space is used for some efficiency in
// some of the MP specific code and is highly implementation-dependent.
//
typedef struct {
UCHAR PCMPApicID;
UCHAR na[3];
} HALPRCB, *PHALPRCB;
//
// interrupt vector definitions for C
//
#define ZERO_VECTOR 0x00 // IRQL 00 placeholder
#define APIC_SPURIOUS_VECTOR 0x1f // IRQL Spurious handler
#define APC_VECTOR 0x3D // IRQL 01 APC
#define DPC_VECTOR 0x41 // IRQL 02 DPC
#define APIC_REBOOT_VECTOR 0x50 // IRQL Vector used to reboot
#define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 broadcast function call
#define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 APIC INTI0 - CLOCK2_LEVEL
#define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 IPI_LEVEL-1
#define APIC_IPI_VECTOR 0xE1 // IRQL 29 APIC IPI
#define APIC_FAULT_VECTOR 0xE3 //
#define POWERFAIL_VECTOR 0xEF // IRQL 30 reserved. not used
#define APIC_PROFILE_VECTOR 0xFD // IRQL 31
#define APIC_PERF_VECTOR 0xFE // IRQL 31
#define NMI_VECTOR 0xFF // IRQL 31
//
// 8259/ISP interrupt controller register addresses
//
#define PIC1_PORT0 0x20
#define PIC1_PORT1 0x21
#ifndef PIC2_PORT0
#define PIC2_PORT0 0xA0
#define PIC2_PORT1 0xA1
#endif
#define PIC_SLAVE_IRQ 2
#define PIC1_ELCR_PORT 0x04D0 // ISP edge/level control registers
#define PIC2_ELCR_PORT 0x04D1
#define PIC1_SPURIOUS_VECTOR 0x37
//
// Defines for HalpFeatureBits
//
extern ULONG HalpFeatureBits;
//
//
//
ULONG FASTCALL HalpAcquireHighLevelLock(PKSPIN_LOCK);
VOID FASTCALL HalpReleaseHighLevelLock(PKSPIN_LOCK, ULONG);
extern KSPIN_LOCK HalpAccountingLock;
extern KAFFINITY HalpActiveProcessors;
//
// Prototypes
//
BOOLEAN
HalpGetPcMpInterruptDesc (
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN ULONG BusInterruptLevel,
OUT PULONG PcMpInti
);
VOID
HalpCheckELCR (
VOID
);
VOID
HalpSetInternalVector (
IN ULONG InternalVector,
IN VOID (*HalInterruptSerivceRoutine)(VOID)
);
VOID
HalpGenericCall (
VOID (*Fnc)(ULONG),
ULONG Context,
KAFFINITY Processors
);
VOID
HalpPollForBroadcast (
VOID
);
ULONG
FASTCALL
HalpWaitForPending (
IN ULONG Count,
IN volatile ULONG *LuICR
);
VOID
HalpPerfInterrupt(
VOID
);
VOID
HalpEnablePerfInterupt (
ULONG Context
);
VOID
HalpEnableNMI (
VOID
);
NTSTATUS
HalpSetSystemInformation (
IN HAL_SET_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
IN PVOID Buffer
);
/*
endif
;
; Begin assembly part of the definitions
;
include i386\pcmp.inc
;
; Well known virtual address of local processor apic
;
LOCALAPIC equ 0fffe0000h
APIC equ ds:[LOCALAPIC]
DEBUGGING equ 0
if DEBUGGING
IRQL_METRICS equ 0
endif
;
; To allow the user to specify command line options to the HAL.
;
USER_SETABLE_OPTIONS equ 1
;
; This OS specific structure holds useful MP information. This information
; is obtained from the PC+MP table and stored here for convenience.
;
HalpMpInfo struc
ApicVersion dd 0 ; 82489Dx or Not
ProcessorCount dd 0 ; Number of Enabled Processors
NtProcessors dd 0 ; Number of Running Processors
BusCount dd 0 ; Number of buses in system
IOApicCount dd 0 ; Number of Io Apics in system
IntiCount dd 0 ; Num of Io Apic interrupt inputs
LintiCount dd 0 ; Num of Local Apic interrupt inputs
IMCRPresent dd 0 ; Indicates if the IMCR is present
LocalApicBase dd 0 ; Base of local apic
IoApicBase dd 8 dup (0) ; The virtual addresses of the IoApics
IoApicPhys dd 8 dup (0) ; The physical addresses of the IoApics
ProcessorEntryPtr dd 0 ; Ptr to 1st PC+MP processor entry
BusEntryPtr dd 0 ; Ptr to 1st PC+MP bus entry
IoApicEntryPtr dd 0 ; Ptr to 1st PC+MP IoApic entry
IntiEntryPtr dd 0 ; Ptr to 1st PC+MP Inti entry
LintiEntryPtr dd 0 ; Ptr to 1st PC+MP Linti entry
ExtensionTable dd 0 ; Ptr to 1st extension table entry
EndExtensionTable dd 0 ; Ptr to 1st extension table entry
HalpMpInfo ends
;
; interrupt vector definitions for assembler
;
ZERO_VECTOR equ 000h ; IRQL 00 placeholder
APIC_SPURIOUS_VECTOR equ 01fh ; Vector used for spurious handler
APC_VECTOR equ 03Dh ; IRQL 01 APC
DPC_VECTOR equ 041h ; IRQL 02 DPC
APIC_REBOOT_VECTOR equ 050h ; Vector used to reboot
DEVICE_LEVEL1 equ 051h
DEVICE_LEVEL2 equ 061h
DEVICE_LEVEL3 equ 071h
DEVICE_LEVEL4 equ 081h
DEVICE_LEVEL5 equ 091h
DEVICE_LEVEL6 equ 0A1h
DEVICE_LEVEL7 equ 0B1h
APIC_GENERIC_VECTOR equ 0C1h ; IRQL 27 broadcast function call
APIC_CLOCK_VECTOR equ 0D1h ; IRQL 28 APIC INTI0 - CLOCK2_LEVEL
APIC_SYNCH_VECTOR equ 0D1h ; IRQL 28 IPI_LEVEL-1
APIC_IPI_VECTOR equ 0E1h ; IRQL 29 APIC IPI
APIC_FAULT_VECTOR equ 0E3h ;
POWERFAIL_VECTOR equ 0EFh ; IRQL 30 reserved
APIC_PROFILE_VECTOR equ 0FDh ; IRQL 27
APIC_PERF_VECTOR equ 0FEh ; IRQL 27
NMI_VECTOR equ 0FFh ; IRQL 31
HAL_PROFILE_LEVEL equ HIGH_LEVEL
;
; 8259/ISP interrupt controller register addresses
;
PIC1_PORT0 equ 020H
PIC1_PORT1 equ 021H
PIC2_PORT0 equ 0A0H
PIC2_PORT1 equ 0A1H
PIC1_ELCR_PORT equ 04D0H ; ISP edge/level control registers
PIC2_ELCR_PORT equ 04D1H
;
; Initialization control words for the PICs
;
ICW1_ICW4_NEEDED equ 01H
ICW1_CASCADE equ 00H
ICW1_INTERVAL8 equ 00H
ICW1_LEVEL_TRIG equ 08H
ICW1_EDGE_TRIG equ 00H
ICW1_ICW equ 10H
ICW4_8086_MODE equ 001H
ICW4_AUTO_EOI equ 002H
ICW4_NORM_EOI equ 000H
ICW4_NON_BUF_MODE equ 000H
ICW4_SPEC_FULLY_NESTED equ 010H
ICW4_NOT_SPEC_FULLY_NESTED equ 000H
PIC_SLAVE_IRQ equ 2
PIC1_BASE equ 30H
PIC2_BASE equ 38H
PIC_CLOCK_VECTOR equ 30H
PIC_DMA_VECTOR equ 3DH
PIC1_SPURIOUS_VECTOR equ 37H
PIC2_SPURIOUS_VECTOR equ 3FH
;
; Operation control words for the PICs
;
OCW2_NON_SPECIFIC_EOI equ 020H
OCW2_SPECIFIC_EOI equ 060H
OCW3_READ_ISR equ 0BH
OCW3_READ_IRR equ 0AH
OCW3_READ_POLLED equ 0CH
;
; A couple of definitions that shouldn't change on a Compatible
;
TimerPicInti equ 0
DmaPic2Inti equ 5
SlavePicInti equ 2
DmaPicInti equ 13 ; DMA input relative to 0
cr equ 0ah
lf equ 0dh
;
; The kernel leaves some space (64 byte) of the PCR for the HAL to use
; as it needs. Currently this space is used for some efficiency in
; some of the MP specific code and is highly implementation-dependent.
;
PcrE struc
PcrNumber db 0 ; Processor's number
ShortDpc db 0 ; Short circut dpc interrupt
DpcPending db 0 ; Dpc interrupt pending
db 0 ; force dword alignment
;
; The next three dwords are used to manipulate the APIC counter
;
ApicClockFreqHz dd 0 ; Counter Freq in Hertz
ApicClockFreqKhz dd 0 ; Counter Freq in Khertz (rounded)
ProfileCountDown dd 0 ; Current Countdown Interval
TSCHz dd 0 ; Time stamp counter hertz low
; PerfCounterLow dd 0 ; PerProcessor Counter
; PerfCounterHigh dd 0 ;
; ProfileCountLast dd 0
PcrE ends
PrcbE struc
PrcbPCMPApicID db 0 ; Processor's PCMP ApicID
db 3 dup (0) ; force dword alignment
PrcbE ends
MsrTSC equ 10h
;++
;
; STALL_WHILE_APIC_BUSY
;
; Wait for the APIC DELIVERY_PENDING bit to be clear
;
;--
STALL_WHILE_APIC_BUSY macro
local a, b
if 0
push eax
mov eax, 5000h
a: test dword ptr APIC[LU_INT_CMD_LOW],DELIVERY_PENDING
jz short b
dec eax
jnz short a
int 3
jmp short a
b: pop eax
else
a: test dword ptr APIC[LU_INT_CMD_LOW],DELIVERY_PENDING
jnz short a
endif
endm
;++
;
; APICFIX
;
; Macro Description:
;
; For internal testing use
;
; Arguments:
;
; None
;
;--
APICFIX macro reg1
; inc dword ptr PCR[PcKernel] ; Count # of times patched
endm
;++
;
; CHECKTPR
;
; Macro Description:
;
; For internal testing use
;
; Arguments:
;
; None
;
;--
CHECKTPR macro reg1, reg2
if DBG
cmp reg1, reg2
je short @f
int 3
@@:
endif
endm
;++
;
; IODELAY
;
; Macro Description:
;
; This macro delays the CPU just a little so the PIC has time to settle
; between IO port accesses. Current mechanism is to read an APIC local
; unit register (eax is saved). Note that PUSHF/POPF is worth 10 clocks.
;
; Arguments:
;
; None
;
;--
IODELAY macro
pushf
popf
jmp $+2
endm
;++
;
; SET_8259_MASK
;
; Macro Description:
;
; This macro sets the 8259 PIC interrupt mask register with the mask
; passed from eax register. Bits 7:0 are the mask for the master PIC
; and bits 15:8 are the mask for the slave PIC.
;
; Arguments:
;
; (eax) = mask for setting 8259 PIC interrupt mask register
;
;--
SET_8259_MASK macro
out PIC1_PORT1, al ; set master 8259 mask
shr eax, 8 ; shift slave 8259 mask to al
out PIC2_PORT1, al ; set slave 8259 mask
endm
;*/