NT4/private/ntos/nthals/halfire/ppc/phsystem.s
2020-09-30 17:12:29 +02:00

488 lines
11 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//++
//
// Copyright (c) 1994 FirePower Systems INC.
//
// Copyright (c) 1994 MOTOROLA, INC. All Rights Reserved. This file
// contains copyrighted material. Use of this file is restricted
// by the provisions of a Motorola Software License Agreement.
//
// Module Name:
//
// pxsystem.s
//
// Abstract:
//
// This module implements the routines to handle system functions:
// Provides system specific info.
// Currently provides processor version type
//
// Author:
// breeze@firepower.com
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
/*
* Copyright (c) 1995 FirePower Systems, Inc.
* DO NOT DISTRIBUTE without permission
*
* $RCSfile: phsystem.s $
* $Revision: 1.7 $
* $Date: 1996/01/11 07:08:26 $
* $Locker: $
*/
#include "kxppc.h"
//++
//
// Routine Description:
//
//
// Arguments:
// HalProcessorRev, in r3
//
//
// Return Value:
// Processor Version register value
//
//
//--
LEAF_ENTRY(HalpGetProcessorRev)
mfpvr r.3 // get processor version
LEAF_EXIT(HalpGetProcessorRev)
/******************************************************************************
Synopsis:
ULONG HalpGetUpperIBAT(ULONG BatNumber) [ged]
Purpose:
Supplies the 32-bit upper instruction BAT value for a given <BatNumber>.
Returns:
Returns the 32-bit upper BAT value.
******************************************************************************/
.set BatNumber, r.3
LEAF_ENTRY(HalpGetUpperIBAT)
cmpli 0,0,BatNumber,0
bne NotUI0
mfibatu BatNumber,0
b ExitUI
NotUI0:
cmpli 0,0,BatNumber,1
bne NotUI1
mfibatu BatNumber,1
b ExitUI
NotUI1:
cmpli 0,0,BatNumber,2
bne NotUI2
mfibatu BatNumber,2
b ExitUI
NotUI2:
mfibatu BatNumber,3 // OK, it's three by default
ExitUI:
LEAF_EXIT(HalpGetUpperIBAT)
/******************************************************************************
Synopsis:
ULONG HalpGetLowerIBAT(ULONG BatNumber) [ged]
Purpose:
Supplies the 32-bit lower instruction BAT value for a given <BatNumber>.
Returns:
Returns the 32-bit lower BAT value.
******************************************************************************/
LEAF_ENTRY(HalpGetLowerIBAT)
cmpli 0,0,BatNumber,0
bne NotLI0
mfibatl BatNumber,0
b ExitLI
NotLI0:
cmpli 0,0,BatNumber,1
bne NotLI1
mfibatl BatNumber,1
b ExitLI
NotLI1:
cmpli 0,0,BatNumber,2
bne NotLI2
mfibatl BatNumber,2
b ExitLI
NotLI2:
mfibatl BatNumber,3 // OK, it's three by default
ExitLI:
LEAF_EXIT(HalpGetLowerIBAT)
/******************************************************************************
Synopsis:
ULONG HalpGetUpperDBAT(ULONG BatNumber) [ged]
Purpose:
Supplies the 32-bit upper data BAT value for a given <BatNumber>.
Returns:
Returns the 32-bit upper BAT value.
******************************************************************************/
LEAF_ENTRY(HalpGetUpperDBAT)
cmpli 0,0,BatNumber,0
bne NotUD0
mfdbatu BatNumber,0
b ExitUD
NotUD0:
cmpli 0,0,BatNumber,1
bne NotUD1
mfdbatu BatNumber,1
b ExitUD
NotUD1:
cmpli 0,0,BatNumber,2
bne NotUD2
mfdbatu BatNumber,2
b ExitUD
NotUD2:
mfdbatu BatNumber,3 // OK, it's three by default
ExitUD:
LEAF_EXIT(HalpGetUpperDBAT)
/******************************************************************************
Synopsis:
ULONG HalpGetLowerDBAT(ULONG BatNumber) [ged]
Purpose:
Supplies the 32-bit lower data BAT value for a given <BatNumber>.
Returns:
Returns the 32-bit lower BAT value.
******************************************************************************/
LEAF_ENTRY(HalpGetLowerDBAT)
cmpli 0,0,BatNumber,0
bne NotLD0
mfdbatl BatNumber,0
b ExitLD
NotLD0:
cmpli 0,0,BatNumber,1
bne NotLD1
mfdbatl BatNumber,1
b ExitLD
NotLD1:
cmpli 0,0,BatNumber,2
bne NotLD2
mfdbatl BatNumber,2
b ExitLD
NotLD2:
mfdbatl BatNumber,3 // OK, it's three by default
ExitLD:
LEAF_EXIT(HalpGetLowerDBAT)
/******************************************************************************
Synopsis:
ULONG HalpSetUpperDBAT(ULONG BatNumber) [rdl]
Purpose:
Stores the 32-bit upper data BAT value for a given <BatNumber>.
Returns:
N/A
******************************************************************************/
.set BatValueToSet, r.4
LEAF_ENTRY(HalpSetUpperDBAT)
cmpli 0,0,BatNumber,0
bne NotSetUD0
mtdbatu 0,BatValueToSet
b ExitSetUD
NotSetUD0:
cmpli 0,0,BatNumber,1
bne NotSetUD1
mtdbatu 1,BatValueToSet
b ExitSetUD
NotSetUD1:
cmpli 0,0,BatNumber,2
bne NotSetUD2
mtdbatu 2,BatValueToSet
b ExitSetUD
NotSetUD2:
mtdbatu 3,BatValueToSet // OK, it's three by default
ExitSetUD:
LEAF_EXIT(HalpSetUpperDBAT)
/******************************************************************************
Synopsis:
ULONG HalpSetLowerDBAT(ULONG BatNumber) [rdl]
Purpose:
Stores the 32-bit lower data BAT value for a given <BatNumber>.
Returns:
N/A
******************************************************************************/
LEAF_ENTRY(HalpSetLowerDBAT)
cmpli 0,0,BatNumber,0
bne NotSetLD0
mtdbatl 0,BatValueToSet
b ExitSetLD
NotSetLD0:
cmpli 0,0,BatNumber,1
bne NotSetLD1
mtdbatl 1,BatValueToSet
b ExitSetLD
NotSetLD1:
cmpli 0,0,BatNumber,2
bne NotSetLD2
mtdbatl 2,BatValueToSet
b ExitSetLD
NotSetLD2:
mtdbatl 3,BatValueToSet // OK, it's three by default
ExitSetLD:
LEAF_EXIT(HalpSetLowerDBAT)
/******************************************************************************
Synopsis:
VOID HalpSetLowerDBAT3(ULONG BatValue) [ged]
Purpose:
Writes the 32-bit lower data BAT value <BatValue> to DBAT3.
Returns:
Nothing
******************************************************************************/
.set BatValue, r.3
LEAF_ENTRY(HalpSetLowerDBAT3)
mtdbatl 3,BatValue
LEAF_EXIT(HalpSetLowerDBAT3)
/******************************************************************************
Synopsis:
VOID HalpSetLowerDBAT1(ULONG BatValue) [ged]
Purpose:
Writes the 32-bit lower data BAT value <BatValue> to DBAT1.
Returns:
Nothing
******************************************************************************/
LEAF_ENTRY(HalpSetLowerDBAT1)
mtdbatl 1,BatValue
LEAF_EXIT(HalpSetLowerDBAT1)
/******************************************************************************
Synopsis:
VOID HalpSetUpperDBAT1(ULONG BatValue) [ged]
Purpose:
Writes the 32-bit upper data BAT value <BatValue> to DBAT1.
Returns:
Nothing
******************************************************************************/
LEAF_ENTRY(HalpSetUpperDBAT1)
mtdbatu 1,BatValue
LEAF_EXIT(HalpSetUpperDBAT1)
/******************************************************************************
Synopsis:
VOID HalpDisableDCache()
******************************************************************************/
LEAF_ENTRY(HalpDisableDCache)
.set HID0, 1008
mtspr HID0, r3
LEAF_EXIT(HalpDisableDCache)
//++
//
// void
// KiSetDbat
//
// Routine Description:
//
// Writes a set of values to DBAT n
//
// No validation of parameters is done. Protection is set for kernel
// mode access only.
//
// Arguments:
//
// r.3 Number of DBAT
// r.4 Physical address
// r.5 Virtual Address
// r.6 Length (in bytes)
// r.7 Coherence Requirements (WIM)
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY (KiSetDbat)
mfpvr r.9 // different format for
// 601 vs other 6xx processors
cmpwi cr.5, r.3, 1
cmpwi cr.6, r.3, 2
cmpwi cr.7, r.3, 3
rlwinm. r.10, r.9, 0, 0xfffe0000// Check for 601
// calculate mask (ie BSM) If we knew the number passed in was
// always a power of two we could just subtract 1 and shift right
// 17 bits. But to be sure we will use a slightly more complex
// algorithm than will always generate a correct mask.
//
// the mask is given by
//
// ( 1 << ( 32 - 17 - cntlzw(Length - 1) ) ) - 1
// == ( 1 << ( 15 - cntlzw(Length - 1) ) ) - 1
addi r.6, r.6, -1
oris r.6, r.6, 1 // ensure min length 128KB
ori r.6, r.6, 0xffff
cntlzw r.6, r.6
subfic r.6, r.6, 15
li r.10, 1
slw r.6, r.10, r.6
addi r.6, r.6, -1
beq cr.0, KiSetDbat601
// processor is not a 601.
rlwinm r.7, r.7, 3, 0x38 // position WIM (G = 0)
rlwinm r.6, r.6, 2, 0x1ffc // restrict BAT maximum (non 601)
// after left shifting by 2.
ori r.6, r.6, 0x2 // Valid (bit) in supervisor state only
ori r.7, r.7, 2 // PP = 0x2
or r.5, r.5, r.6 // = Virt addr | BL | Vs | Vp
or r.4, r.4, r.7 // = Phys addr | WIMG | 0 | PP
beq cr.5, KiSetDbat1
beq cr.6, KiSetDbat2
beq cr.7, KiSetDbat3
KiSetDbat0:
mtdbatl 0, r.4
mtdbatu 0, r.5
ALTERNATE_EXIT(KiSetDbat)
KiSetDbat1:
mtdbatl 1, r.4
mtdbatu 1, r.5
ALTERNATE_EXIT(KiSetDbat)
KiSetDbat2:
mtdbatl 2, r.4
mtdbatu 2, r.5
ALTERNATE_EXIT(KiSetDbat)
KiSetDbat3:
mtdbatl 3, r.4
mtdbatu 3, r.5
ALTERNATE_EXIT(KiSetDbat)
// 601 has different format BAT registers and actually only has
// one set unlike other PowerPC processors which have seperate
// Instruction and Data BATs. The 601 BAT registers are set
// with the mtibat[u|l] instructions.
KiSetDbat601:
rlwinm r.7, r.7, 3, 0x70 // position WIMG (601 has no G bit)
rlwinm r.6, r.6, 0, 0x3f // restrict BAT maximum (601 = 8MB)
ori r.6, r.6, 0x40 // Valid bit
ori r.7, r.7, 4 // Ks = 0 | Ku = 1 | PP = 0b00
or r.4, r.4, r.6 // = Phys addr | Valid | BL
or r.5, r.5, r.7 // = Virt addr | WIM | Ks | Ku | PP
beq cr.5, KiSet601Bat1
beq cr.6, KiSet601Bat2
beq cr.7, KiSet601Bat3
KiSet601Bat0:
mtibatl 0, r.4
mtibatu 0, r.5
ALTERNATE_EXIT(KiSet601Bat)
KiSet601Bat1:
mtibatl 1, r.4
mtibatu 1, r.5
ALTERNATE_EXIT(KiSet601Bat)
KiSet601Bat2:
mtibatl 2, r.4
mtibatu 2, r.5
ALTERNATE_EXIT(KiSet601Bat)
KiSet601Bat3:
mtibatl 3, r.4
mtibatu 3, r.5
LEAF_EXIT(KiSetDbat)
/******************************************************************************
Synopsis:
ULONG HalpGetHighVector(ULONG IntValue)
Purpose:
Find the highest bit turned on and return the bit order
Returns:
Number of leading zeroes
******************************************************************************/
.set IntValue, r.3
LEAF_ENTRY(HalpGetHighVector)
cntlzw IntValue, IntValue
subfic IntValue, IntValue, 0x1f
LEAF_EXIT(HalpGetHighVector)