2020-09-30 17:12:29 +02:00

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)