mirror of https://github.com/lianthony/NT4.0
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.
187 lines
4.5 KiB
187 lines
4.5 KiB
// TITLE("Processor Idle Support")
|
|
//++
|
|
//
|
|
// Copyright (c) 1992 Digital Equipment Corporation
|
|
// Copyright (c) 1993 Digital Equipment Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// idle.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the HalProcessorIdle interface
|
|
//
|
|
// Author:
|
|
//
|
|
// John Vert (jvert) 11-May-1994
|
|
//
|
|
// Environment:
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Wim Colgate, 11-Nov-1995
|
|
//
|
|
// Modified stub routine to idle the processor on LX3.
|
|
//
|
|
//--
|
|
#include "halalpha.h"
|
|
#include "lx3.h"
|
|
|
|
|
|
SBTTL("Processor Idle")
|
|
//++
|
|
//
|
|
// VOID
|
|
// HalProcessorIdle(
|
|
// VOID
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function is called when the current processor is idle with
|
|
// interrupts disabled. There is no thread active and there are no
|
|
// DPCs to process. Therefore, power can be switched to a standby
|
|
// mode until the the next interrupt occurs on the current processor.
|
|
//
|
|
// N.B. This routine is entered with interrupts disabled. This routine
|
|
// must do any power management enabling necessary, enable interrupts,
|
|
// then either return or wait for an interrupt.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
// Note:
|
|
//
|
|
// On LX3, the sequence of events should are:
|
|
//
|
|
// Write "idle" to processor
|
|
// Flush Dcache
|
|
// Enable Interrupts
|
|
//
|
|
// All of the above MUST be loaded into the Icache of the processor
|
|
// once we write "idle" to the processor
|
|
//
|
|
// Once the processor is idle, we cannot get to the backup cache,
|
|
// nor main memory. Once an interrupt occurs, the CPU reattaches via
|
|
// hardware magic.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(HalProcessorIdle)
|
|
|
|
//
|
|
// Enable, then disable interrups to force the PALcode
|
|
// enable_interrupt routine into the Icache -- by executing it,
|
|
// then back to interrupts disabled.
|
|
//
|
|
|
|
ENABLE_INTERRUPTS
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
|
|
//
|
|
// set up temps here - instead of in critical Icache area
|
|
// temps are a0-a5, t0-t7
|
|
//
|
|
|
|
lda a0, HalpInterruptReceived
|
|
bis zero, 1, t3
|
|
stl t3, 0(a0)
|
|
|
|
//
|
|
// set up t5 for superpage mode base address
|
|
//
|
|
|
|
ldiq t5, -0x4000 // 0xffff ffff ffff c000
|
|
sll t5, 28, t5 // 0xffff fc00 0000 0000
|
|
|
|
//
|
|
// set t7 for interrupt register to poll on
|
|
//
|
|
|
|
ldah t7, 0x1b(zero) // 0x0000 0000 1b00 0000
|
|
sll t7, 4, t7 // 0x0000 0001 b000 0000
|
|
|
|
bis t5, t7, t7 // 0xffff fc01 b000 0000
|
|
|
|
//
|
|
// set t6 for a 32K constant for Dcache flushing
|
|
//
|
|
|
|
ldil t6, 0x8000 // 0x0000 0000 0000 8000
|
|
|
|
//
|
|
// set a1 to be the 'bouncing' bit
|
|
//
|
|
|
|
bis zero, 1, a1
|
|
|
|
mb
|
|
|
|
DISABLE_INTERRUPTS
|
|
|
|
//
|
|
// Flush Dcache -- start at superpage address 0 and read 32K worth of
|
|
// data
|
|
//
|
|
|
|
flush: ldl t1, 0(t5) // read data
|
|
addl t5, 0x20, t5 // increment location by 8 longwords
|
|
and t5, t6, t4 // check for 32K limit
|
|
bne t4, setspin // loop finished
|
|
br zero, flush // branch back
|
|
|
|
bne a1, touch1 // bounce ahead to touch1
|
|
|
|
continue:
|
|
|
|
//
|
|
// clear a1 (aka the bouncing bit) so that we actually execite code
|
|
// now.
|
|
|
|
bis zero, zero, a1
|
|
|
|
//
|
|
// Power down the processor to 'idle speed', which is not
|
|
// completelty off. Duh.
|
|
//
|
|
|
|
ldil t0, CONFIG_REGISTER_SMALL // 0x0000 0000 0000 1001
|
|
sll t0, 20, t0 // 0x0000 0001 0010 0000
|
|
|
|
bis t0, t5, t0 // 0xffff fc01 0010 0000
|
|
|
|
ldil t2, CONFIG_SELECT_IDLE // load idle setting
|
|
stl t2, 0(t0) // set processor to idle
|
|
|
|
//
|
|
// Past this point, all instructions MUST be in the Icache
|
|
//
|
|
|
|
//
|
|
// Enable Interrupts
|
|
//
|
|
|
|
setspin:
|
|
ENABLE_INTERRUPTS
|
|
|
|
//
|
|
// spin on the interrupt bit -- cleared by any interrupt routine
|
|
//
|
|
|
|
spin: ldl t0, 0(a0) // load bit
|
|
bne t0, spin // spin on bit
|
|
|
|
touch1: bne a1, continue // go all the way back
|
|
|
|
#endif
|
|
|
|
done: ret zero, (ra)
|
|
|
|
.end HalProcessorIdle
|