#if defined(R4000)
//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk35/src/hal/halsni/mips/RCS/x4misc.s,v 1.4 1995/02/13 12:54:22 flo Exp $")
// TITLE("Misc R4000 Functions")
//++
//
// Copyright (c) 1994 Siemens Nixdorf Informationssysteme AG
//
// Module Name:
//
// x4misc.s
//
// Abstract:
//
// This module implements some R4000 basic register access routines
//
// Environment:
//
// Kernel mode only.
//
//--
#include "halmips.h"
#include "SNIdef.h"
#define STATUS_DE 0x10000 // Disable Cache error ands ECC Errors bit
#define STATUS_IE 0x00001 // Interrupt Enable/Disable Bit
#define UNCACHED 0x2
#define CACHABLE_NONCOHERENT 0x3
#define CACHABLE_COHERENT_EXCLUSIVE 0x4
#define CACHABLE_COHERENT_EXCLUSIVE_ON_WRITE 0x5
#define CACHABLE_COHERENT_UPDATE_ON_WRITE 0x6
SBTTL("Get R4000 Status Register")
//++
//
// ULONG
// HalpGetStatusRegister(
// VOID
// )
//
// Routine Description:
//
// This function returns the current value of the status register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the Status register.
//
//--
LEAF_ENTRY(HalpGetStatusRegister)
.set noreorder
.set noat
mfc0 v0,psr // get current PSR
nop // fill
nop
nop
nop
.set at
.set reorder
j ra // return
.end HalpGetStatusRegister
SBTTL("Set R4000 Status Register")
//++
//
// ULONG
// HalpSetStatusRegister(
// VOID
// )
//
// Routine Description:
//
// This function sets the status register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The previous value of the Status register.
//
//--
LEAF_ENTRY(HalpSetStatusRegister)
.set noreorder
.set noat
mfc0 v0,psr // get current (old)PSR
nop // fill
nop
nop
nop
mtc0 a0,psr
.set at
.set reorder
j ra // return
.end HalpSetStatusRegister
SBTTL("Get R4000 Cause Register")
//++
//
// ULONG
// HalpGetCauseRegister(
// VOID
// )
//
// Routine Description:
//
// This function returns the current value of the cause register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the cause register.
//
//--
LEAF_ENTRY(HalpGetCauseRegister)
.set noreorder
.set noat
mfc0 v0,cause // get current cause
nop // fill
nop
nop
nop
.set at
.set reorder
j ra // return
.end HalpGetCauseRegister
SBTTL("Set R4000 Cause Register")
//++
//
// ULONG
// HalpSetCauseRegister(
// VOID
// )
//
// Routine Description:
//
// This function sets the Cause register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The previous value of the Cause register.
//
//--
LEAF_ENTRY(HalpSetCauseRegister)
.set noreorder
.set noat
mfc0 v0,cause // get current (old)Cause
nop // fill
nop
nop
nop
mtc0 a0,cause
nop
nop
nop
.set at
.set reorder
j ra // return
.end HalpSetCauseRegister
SBTTL("Get R4000 Config Register")
//++
//
// ULONG
// HalpGetConfigRegister(
// VOID
// )
//
// Routine Description:
//
// This function returns the current value of the Config register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the Config register.
//
//--
LEAF_ENTRY(HalpGetConfigRegister)
.set noreorder
.set noat
mfc0 v0,config // get current Config
nop // fill
nop
nop
nop
.set at
.set reorder
j ra // return
.end HalpGetConfigRegister
SBTTL("Set R4000 Config Register")
//++
//
// ULONG
// HalpSetConfigRegister(
// VOID
// )
//
// Routine Description:
//
// This function sets the R4000 Config register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The previous value of the Config register.
//
//--
LEAF_ENTRY(HalpSetConfigRegister)
.set noreorder
.set noat
mfc0 v0,config // get current (old)Config
nop // fill
nop
nop
nop
mtc0 a0,config
nop
nop
nop
nop
.set at
.set reorder
j ra // return
.end HalpSetConfigRegister
SBTTL("Dismiss (acknowledge) Timeout Interrupts")
//++
//
// ULONG
// HalpDismissTimeoutInterrupts(
// VOID
// )
//
// Routine Description:
//
// This function it is called as an result of an (single) Timeout Interrupt
// we reset the Bit 21 of the IOMemconf Register (disable Timeout) wait
// and than we reenable Timeout Interrupts by setting Bit 21
//
// Note: Because the SNI ASIC is located at a special Address,
// ( I have to study the docs again ...)
// We have to set the Disable Parity Error and ECC Detection Bit in the
// R4x00 Status register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the Status register.
//
//--
LEAF_ENTRY(HalpDismissTimeoutInterrupts)
.set noreorder
mfc0 v0,psr // get current PSR
nop // fill
nop
nop
or v1, v0, STATUS_DE // disable Parity/ Cache errors
and v1, v1, ~(STATUS_IE) // disable Interrupts
mtc0 v1, psr
nop
nop
nop
li t0, IOMEMCONF_ADDR // Timeout (and other) register
lw a0, 0(t0) // get the current value
and a1, a0, 0xffdfffff // reset bit 21
sw a1, 0(t0) // set IOMemconf Register
sync // flush write buffers
//
// execute a small time loop
//
li a1,0x10
1: nop
bne a1,zero,1b
subu a1,1 // BDSLOT
sw a0,0(t0) // restore old IOMemconf Register value
sync // flush write buffers
mtc0 v0, psr // restore old R4000 Status Register
nop
nop
nop
nop
.set reorder
j ra // return
.end HalpDismissTimeoutInterrupts
SBTTL("Disable Timeout Interrupts")
//++
//
// ULONG
// HalpDisableTimeoutInterrupts(
// VOID
// )
//
// Routine Description:
//
// This function it is called as an result of LOTS of LOTS of Timeout Interrupts,
// so we disable them in the IOMemconfRegister (bit 21)
// this is a stripped down version of HalpDismissTimeoutInterrupts()
//
// Note: Because the SNI ASIC is located at a special Address,
// ( I have to study the docs again ...)
// We have to set the Disable Parity Error and ECC Detection Bit in the
// R4x00 Status register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the Status register.
//
//--
LEAF_ENTRY(HalpDisableTimeoutInterrupts)
.set noreorder
mfc0 v0,psr // get current PSR
nop // fill
nop
nop
or v1, v0, STATUS_DE // disable Parity/ Cache errors
and v1, v1, ~(STATUS_IE) // disable Interrupts
mtc0 v1, psr
nop
nop
nop
li t0, IOMEMCONF_ADDR // Timeout (and other) register
lw a0, 0(t0) // get the current value
and a1, a0, 0xffdfffff // reset bit 21
sw a1, 0(t0) // set register
sync // flush write buffers
mtc0 v0, psr // restore old R4000 Status Register
nop
nop
nop
nop
.set reorder
j ra // return
.end HalpDisableTimeoutInterrupts
SBTTL("Enable Timeout Interrupts")
//++
//
// ULONG
// HalpEnableTimeoutInterrupts(
// VOID
// )
//
// Routine Description:
//
// This function is the Counterpart of HalpDisableTimeoutInterrupts
// We hope, it is never called
//
// Note: Because the SNI ASIC is located at a special Address,
// ( I have to study the docs again ...)
// We have to set the Disable Parity Error and ECC Detection Bit in the
// R4x00 Status register
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// The value of the Status register.
//
//--
LEAF_ENTRY(HalpEnableTimeoutInterrupts)
.set noreorder
mfc0 v0,psr // get current PSR
nop // fill
nop
nop
or v1, v0, STATUS_DE // disable Parity/ Cache errors
and v1, v1, ~(STATUS_IE) // disable Interrupts
mtc0 v1, psr
nop
nop
nop
li t0, IOMEMCONF_ADDR // Timeout (and other) register
lw a0, 0(t0) // get the current value
or a1, a0, 0x00200000 // set bit 21
sw a1, 0(t0) // set register
sync // flush write buffers
mtc0 v0, psr // restore old R4000 Status Register
nop
nop
nop
.set reorder
j ra // return
.end HalpEnableTimeoutInterrupts
#endif