488 lines
11 KiB
ArmAsm
488 lines
11 KiB
ArmAsm
|
//++
|
|||
|
//
|
|||
|
// 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)
|