summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/hal0jens/alpha/jxinitnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/hal0jens/alpha/jxinitnt.c')
-rw-r--r--private/ntos/nthals/hal0jens/alpha/jxinitnt.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/private/ntos/nthals/hal0jens/alpha/jxinitnt.c b/private/ntos/nthals/hal0jens/alpha/jxinitnt.c
new file mode 100644
index 000000000..e1fb48218
--- /dev/null
+++ b/private/ntos/nthals/hal0jens/alpha/jxinitnt.c
@@ -0,0 +1,471 @@
+#if defined(JENSEN)
+
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+Copyright (c) 1992 Digital Equipment Corporation
+
+Module Name:
+
+ .../ntos/hal/alpha/jxinitnt.c
+
+Abstract:
+
+
+ This module implements the interrupt initialization for an Alpha/Jensen
+ system. Contains the VLSI 82C106, the 82357 and an EISA bus.
+
+ Stolen from Dave Cutler's jxinitnt.c in ../mips
+
+Author:
+
+ David N. Cutler (davec) 26-Apr-1991
+ Jeff McLeman (DEC) 18-May-1992
+ Miche Baker-Harvey (miche) 18-May-1992
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+ Jeff McLeman (DEC) 30-Jul-1992
+ Remove Clock interrupt from this module, because it is done
+ in JXCLOCK.C
+--*/
+
+#include "halp.h"
+#include "jnsnrtc.h"
+#include "jnsndef.h"
+#include "jxserp.h"
+#include "eisa.h"
+
+
+
+//
+// Define global data for builtin device interrupt enables.
+//
+
+USHORT HalpBuiltinInterruptEnable;
+
+
+// irql mask and tables
+//
+// irql 0 - passive
+// irql 1 - sfw apc level
+// irql 2 - sfw dispatch level
+// irql 3 - device low (All devices except)
+// irql 4 - device high (the serial lines)
+// irql 5 - clock
+// irql 6 - real time
+// irql 7 - error, mchk, nmi, halt
+//
+//
+// IDT mappings:
+// For the built-ins, GetInterruptVector will need more info,
+// or it will have to be built-in to the routines, since
+// these don't match IRQL levels in any meaningful way.
+//
+// 0 passive 8
+// 1 apc 9
+// 2 dispatch 10 PIC
+// 3 11 keyboard/mouse
+// 4 serial 12 errors
+// 5 clock 13 parallel
+// 6 14 halt
+// 7 nmi 15
+//
+// This is assuming the following prioritization:
+// nmi
+// halt
+// errors
+// clock
+// serial
+// parallel
+// keyboard/mouse
+// pic
+
+//
+// This is the HalpIrqlMask for Jensen
+// Jensen interrupt pins:
+//
+// eirq 0 interval timer from 82c106
+// eirq 1 PIC - 82357 interrupts
+// eirq 2 NMI from the ISP
+// eirq 3 Keyboard and Mouse (82c106)
+// eirq 4 Front-panel HALT switch
+// eirq 5 serial ports A and B.
+// (note that the parallel printer from the 82c106 comes in on the PIC)
+
+#include "jxirql.h"
+
+//
+// For information purposes: here is what the IDT division looks like:
+//
+// 000-015 Built-ins (we only use 8 entries; NT wants 10)
+// 016-031 ISA
+// 048-063 EISA
+// 080-095 PCI
+// 112-127 Turbo Channel
+// 128-255 unused, as are all other holes
+//
+
+VOID
+HalpClearInterrupts(
+ );
+
+VOID
+HalpHaltInterrupt(
+ );
+
+
+BOOLEAN
+HalpInitializeInterrupts (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function initializes interrupts for an Alpha system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the initialization is successfully
+ completed. Otherwise a value of FALSE is returned.
+
+--*/
+
+{
+
+ UCHAR DataByte;
+ ULONG DataLong;
+ ULONG Index;
+ extern VOID KeUpdateSystemTime(VOID);
+
+ //
+ // Initialize HAL processor parameters based on estimated CPU speed.
+ // This must be done before HalpStallExecution is called. Compute integral
+ // megahertz first to avoid rounding errors due to imprecise cycle clock
+ // period values.
+ //
+
+ HalpInitializeProcessorParameters();
+
+ //
+ // Initialize the IRQL translation table in the PCR. These tables are
+ // used by the interrupt dispatcher to determine the new irql, and to
+ // determine the vector into the IDT. This is a bit different from
+ // "normal" NT, which uses the IRQL to index into the vector table directly.
+ // Since we have more information about who has interrupted (from the CPU
+ // interrupt pins), we use that information to get directly to the vector
+ // for the builting device which has interrupted.
+ //
+
+
+ for (Index = 0; Index < (sizeof(HalpIrqlMask)/4); Index++){
+ PCR->IrqlMask[Index].IrqlTableIndex = HalpIrqlMask[Index].IrqlTableIndex;
+ PCR->IrqlMask[Index].IDTIndex = HalpIrqlMask[Index].IDTIndex;
+ }
+
+ for (Index = 0; Index < (sizeof(HalpIET)/4); Index++){
+ PCR->IrqlTable[Index] = HalpIET[Index];
+ }
+
+
+
+ //
+ // Connect the Stall interrupt vector to the clock. When the
+ // profile count is calculated, we then connect the normal
+ // clock.
+
+
+ PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpStallInterrupt;
+
+ //
+ // Register the Halt interrupt
+ //
+
+ PCR->InterruptRoutine[HALT_VECTOR] = (PKINTERRUPT_ROUTINE)HalpHaltInterrupt;
+
+ HalpInitializeProfiler();
+
+ //
+ // Clear all pending interrupts
+ //
+
+ HalpClearInterrupts();
+
+ //
+ // Start the peridodic interrupt from the RTC
+ //
+ HalpProgramIntervalTimer(MAXIMUM_RATE_SELECT);
+
+ //
+ // Later there must be initialization for the local interrupts
+ // and PIC, but not now ....
+
+
+ return TRUE;
+
+}
+
+
+VOID
+HalpClearInterrupts(
+ )
+/*++
+
+Routine Description:
+
+ This function clears all pending interrupts on the Jensen.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+PSP_READ_REGISTERS SP_READ;
+PSP_WRITE_REGISTERS SP_WRITE;
+UCHAR tmp;
+int i;
+UCHAR btmp;
+UCHAR DataByte;
+
+//
+// clear out VTI interrupts, except the RTC
+//
+
+#ifdef JMBUG
+ //
+ // Reset the EISA bus. This is a draconian way of clearing out any
+ // residual interrupts. It has to be done here in Phase 0, because
+ // unlike the Jazz machine, our I/O and graphics are on EISA. If we
+ // were to pull EISA reset in Phase 1, we would lose device context.
+ // Sort of like changing your sparkplugs while driving 65 MPH on
+ // interstate 5.
+
+ DataByte = 0;
+
+ ((PNMI_EXTENDED_CONTROL) &DataByte)->BusReset = 1;
+
+ WRITE_PORT_UCHAR(
+ (PUCHAR)(&((PEISA_CONTROL)DMA_VIRTUAL_BASE)->ExtendedNmiResetControl),
+ DataByte
+ );
+
+ //
+ // Use a stall loop since KeStallExecutionProcessor isn't available in
+ // Phase 0.
+ //
+
+ HalpStallExecution(4);
+
+ DataByte = 0;
+
+ WRITE_PORT_UCHAR(
+ (PUCHAR)(&((PEISA_CONTROL)DMA_VIRTUAL_BASE)->ExtendedNmiResetControl),
+ DataByte
+ );
+#endif
+
+ //
+ // COM1
+ //
+
+ //
+ // clear the interrupt enable
+ //
+
+ outVti(0x3f9, 0x0);
+ HalpStallExecution(3);
+
+ //
+ // clear out port 1 interrupts
+ //
+
+ outVti(0x3fc, 0x0f);
+ HalpStallExecution(3);
+
+ tmp = inVti(0x3fb);
+ tmp &= ~0xc0;
+ outVti(0x3fb, tmp);
+ HalpStallExecution(3);
+
+ for (i = 0; i< 15; i++) {
+ tmp = inVti(0x3f8);
+ HalpStallExecution(3);
+ if (!inVti(0x3fd) & 1) {
+ break;
+ }
+ }
+
+ for (i = 0; i< 1000; i++) {
+ if(!(0x3fe & 0x0f)) {
+ break;
+ }
+ }
+
+ for (i = 0; i< 5; i++) {
+ if (inVti(0x3fa) & 1) {
+ break;
+ }
+ }
+
+ //
+ // clear the interrupt enable
+ //
+
+ outVti(0x3f9, 0x0);
+ HalpStallExecution(3);
+ //DbgPrint("COM1: Interrupt Enable = %x\n", inVti(0x3f9));
+
+ //
+ // COM2
+ //
+
+ //
+ // clear the interrupt enable
+ //
+
+ outVti(0x2f9, 0x0);
+ HalpStallExecution(3);
+
+ //
+ // clear out port 2 interrupts
+ //
+
+ outVti(0x2fc, 0x0f);
+ HalpStallExecution(3);
+
+ tmp = inVti(0x2fb);
+ tmp &= ~0xc0;
+ outVti(0x2fb, tmp);
+ HalpStallExecution(3);
+
+ for (i = 0; i< 15; i++) {
+ tmp = inVti(0x2f8);
+ HalpStallExecution(3);
+ if (!inVti(0x2fd) & 1) {
+ break;
+ }
+ }
+
+ for (i = 0; i< 1000; i++) {
+ if(!(0x2fe & 0x0f)) {
+ break;
+ }
+ }
+
+ for (i = 0; i< 5; i++) {
+ if (inVti(0x2fa) & 1) {
+ break;
+ }
+ }
+
+ //
+ // clear the interrupt enable
+ //
+
+ outVti(0x2f9, 0x0);
+ HalpStallExecution(3);
+ //DbgPrint("COM2: Interrupt Enable = %x\n", inVti(0x2f9));
+
+ //
+ // Kbd and Mouse
+ //
+
+ outVti(0x64, 0x60);
+ HalpStallExecution(3);
+ outVti(0x60, 0x0);
+ HalpStallExecution(3);
+ tmp = inVti(0x60);
+ while (inVti(0x64) & 1) {
+ HalpStallExecution(3);
+ tmp = inVti(0x60);
+ }
+
+
+ return;
+}
+
+VOID
+HalpStallExecution(
+ ULONG Microseconds
+ )
+
+/*++
+
+Routine Description:
+
+ This function is used internally to the HAL on Alpha AXP systems to
+ stall execution before KeStallExecutionProcessor is available.
+
+Arguments:
+
+ Microseconds - Supplies the number of microseconds to stall.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ LONG StallCyclesRemaining; // signed value
+ ULONG PreviousRpcc, CurrentRpcc;
+
+
+ //
+ // Get the value of the RPCC as soon as we enter
+ //
+
+ PreviousRpcc = HalpRpcc();
+
+ //
+ // Compute the number of cycles to stall
+ //
+
+ StallCyclesRemaining = Microseconds * HalpClockMegaHertz;
+
+ //
+ // Wait while there are stall cycles remaining.
+ // The accuracy of this routine is limited by the
+ // length of this while loop.
+ //
+
+ while (StallCyclesRemaining > 0) {
+
+ CurrentRpcc = HalpRpcc();
+
+ //
+ // The subtraction always works because the Rpcc
+ // is a wrapping long-word. If it wraps, we still
+ // get the positive number we want.
+ //
+
+ StallCyclesRemaining -= (CurrentRpcc - PreviousRpcc);
+
+ //
+ // remember this RPCC value
+ //
+
+ PreviousRpcc = CurrentRpcc;
+ }
+
+}
+
+#endif