241 lines
5.8 KiB
ArmAsm
241 lines
5.8 KiB
ArmAsm
//++
|
|
//
|
|
// Copyright (c) 1993 IBM Corporation
|
|
//
|
|
// 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:
|
|
//
|
|
// pxreset.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the routine HalpPowerPcReset, which can be
|
|
// used to return the PowerPC to Big Endian with cache flushed and
|
|
// branches to the rom based machine reset handler.
|
|
//
|
|
// Author:
|
|
//
|
|
// Steve Johns Sept-1994
|
|
//
|
|
// Environment:
|
|
//
|
|
// Kernel mode only.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// 3/21/95 saj Fixed HID0 getting trashed.
|
|
//--
|
|
|
|
#include "kxppc.h"
|
|
.new_section .text,"crx5"
|
|
|
|
.extern HalpIoControlBase
|
|
.extern HalpSystemType
|
|
|
|
.set ISA, r.1
|
|
|
|
.set HID0, 1008
|
|
.set DISABLES, MASK_SPR(MSR_EE,1) | MASK_SPR(MSR_DR,1) | MASK_SPR(MSR_IR,1)
|
|
.set HID0_DCE, 0x4000 // 603 Data Cache Enable
|
|
.set HID0_ICE, 0x8000 // 603 Instruction Cache Enable
|
|
.set HID0_ICFI, 0x0800 // I-Cache Flash Invalidate
|
|
.set HID0_DCFI, 0x0400 // D-Cache Flash Invalidate
|
|
|
|
|
|
LEAF_ENTRY(HalpPowerPcReset)
|
|
|
|
|
|
lwz r.3,[toc]HalpSystemType(r.toc) // Get system type for later use.
|
|
lwz r.3, 0(r.3)
|
|
|
|
LWI (r.4, 0xfff00100) // Address of ROM reset vector
|
|
mfspr r.5, HID0
|
|
|
|
LWI (r.7, 0x80000000) // I/O space for physical mode
|
|
|
|
lwz ISA,[toc]HalpIoControlBase(r.toc)
|
|
lwz ISA,0(ISA) // Get base address of ISA I/O space
|
|
|
|
|
|
LWI (r.12, 0x800000A8) // Index to Eagle register 0xA8
|
|
stw r.12, 0xCF8(ISA)
|
|
sync
|
|
lwz r.6, 0xCFC(ISA)
|
|
rlwinm r.6, r.6, 0, 0, 29 // Disable L2 cache
|
|
rlwinm r.6, r.6, 0, 21, 19 // Disable Machine Checks from Eagle
|
|
stw r.6, 0xCFC(ISA) // Disable the L2 cache
|
|
rlwinm r.6, r.6, 0, 27, 25 // Clear LE_MODE of Eagle register A8
|
|
|
|
mfmsr r.8
|
|
rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_EE,1)
|
|
isync
|
|
mtmsr r.8 // disable interrupts
|
|
cror 0,0,0 // N.B. 603e/ev Errata 15
|
|
|
|
bl here // get current address
|
|
here:
|
|
mflr r.9 // (r.9) = &here
|
|
addi r.9, r.9, BigEndian-here
|
|
rlwinm r.9, r.9, 0, 0x7fffffff // convert address to physical
|
|
|
|
|
|
// When we get here
|
|
// r.4 contains the address of the ROM resident Machine Reset
|
|
// handler.
|
|
// r.5 contains HID0 present value.
|
|
// r.6 contains Eagle register A8 value for switching to Big Endian
|
|
// r.7 contains the port address (real) used to switch memory
|
|
// endianness.
|
|
// r.8 contains MSR present value.
|
|
// r.9 contains the physical address of "BigEndian"
|
|
|
|
|
|
|
|
// Disable D-Cache and Data address translation, flush I-Cache
|
|
// and disable interrupts.
|
|
|
|
mr r.10, r.5
|
|
ori r.5,r.5,HID0_DCE+HID0_ICE+HID0_ICFI+HID0_DCFI // Invalidate caches
|
|
rlwinm r.10, r.10, 0, ~HID0_DCE// turn off D-cache
|
|
rlwinm r.10, r.10, 0, ~HID0_ICE// turn off I-cache
|
|
sync
|
|
mtspr HID0, r.5 // Flash invalidate both caches
|
|
mtspr HID0, r.10 // Disable both caches
|
|
|
|
rlwinm r.8, r.8, 0, ~MASK_SPR(MSR_DR,1)
|
|
isync
|
|
mtmsr r.8 // disable data address translation,
|
|
// disable interrupts.
|
|
cror 0,0,0 // N.B. 603e/ev Errata 15
|
|
|
|
// We will use a MTMSR instruction to switch to big-endian, untranslated,
|
|
// interrupts disabled at the same time. We use an RFI to effect the
|
|
// branch to the reset vector (0xFFF00100).
|
|
|
|
li r.8, MASK_SPR(MSR_IP,1)
|
|
ori r.8, r.8, MASK_SPR(MSR_ME,1)
|
|
mtsrr1 r.8 // state = Machine Check Enabled
|
|
mtsrr0 r.9 // RFI to BigEndian
|
|
|
|
|
|
//
|
|
// Try to issue a hard reset. If this fails, the fall
|
|
// thru and continue to manually return to firmware.
|
|
//
|
|
|
|
cmpwi r.3, 0 // Skip port 92 reset for BigBend. *BJ*
|
|
beq NoPort92
|
|
|
|
li r.9, 0xFF // All ones
|
|
stb r.9, 0x92(r.7) // Reset the System
|
|
eieio
|
|
lwz r.9, 0x21(r.7) // Flush the Eagle write buffers
|
|
sync
|
|
sync
|
|
sync
|
|
sync
|
|
|
|
//
|
|
// Continue returning to firmware...
|
|
//
|
|
|
|
|
|
NoPort92:
|
|
|
|
|
|
stw r.12, 0xCF8(r.7)
|
|
sync
|
|
stw r.6, 0xCFC(r.7) // switch PCI bus to big-endian (Eagle)
|
|
li r.6, 0
|
|
sync
|
|
rfi
|
|
|
|
|
|
.align 5
|
|
|
|
//
|
|
// When the assembler mode is Big-Endian, instructions are stored in the .OBJ
|
|
// in a different order. To be safe, we will place instructions in groups of
|
|
// fours, where the execution order within a group is not important.
|
|
BigEndian:
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
addi r.0, r.1, 0x138 // same both ways
|
|
|
|
|
|
//
|
|
// Return the processor as close as possible to the reset state
|
|
//
|
|
mtibatl 0, r.6 // Invalidate BAT registers
|
|
mtibatu 0, r.6
|
|
mtibatl 1, r.6
|
|
mtibatu 1, r.6
|
|
mtibatl 2, r.6
|
|
mtibatu 2, r.6
|
|
mtibatl 3, r.6
|
|
mtibatu 3, r.6
|
|
|
|
mtsr 0, r.6 // Zero the Segment Registers
|
|
mtsr 1, r.6
|
|
mtsr 2, r.6
|
|
mtsr 3, r.6
|
|
mtsr 4, r.6
|
|
mtsr 5, r.6
|
|
mtsr 6, r.6
|
|
mtsr 7, r.6
|
|
mtsr 8, r.6
|
|
mtsr 9, r.6
|
|
mtsr 10, r.6
|
|
mtsr 11, r.6
|
|
mtsr 12, r.6
|
|
mtsr 13, r.6
|
|
mtsr 14, r.6
|
|
mtsr 15, r.6
|
|
|
|
mtsprg 0,r.6 // Should get cleared in the firmware
|
|
mtsprg 1,r.6 // (used for branch table)
|
|
mtsprg 2,r.6
|
|
mtsprg 3,r.6
|
|
|
|
li r.9,-1 // DECREMENTER = 0xFFFFFFFF
|
|
mtdec r.9
|
|
li r.9, 128 // # TLBs on a 604 (603 has 32)
|
|
mtsrr0 r.4 // rfi target = 0xfff00100
|
|
|
|
li r.7, 0
|
|
mtctr r.9
|
|
nop
|
|
nop
|
|
|
|
Invalidate_TLB:
|
|
tlbie r.7 // Invalidate Instruction & Data TLBs
|
|
nop
|
|
nop
|
|
nop
|
|
|
|
addi r.7, r.7, 4096 // next TLB
|
|
nop
|
|
nop
|
|
nop
|
|
|
|
bdnz Invalidate_TLB
|
|
nop
|
|
nop
|
|
nop
|
|
|
|
rfi // go to machine reset handler
|
|
rfi
|
|
rfi
|
|
rfi
|
|
|
|
LEAF_EXIT(HalpPowerPcReset)
|