172 lines
3.9 KiB
ArmAsm
172 lines
3.9 KiB
ArmAsm
/*
|
|
* Copyright (c) 1995 FirmWorks, Mountain View CA USA. All rights reserved.
|
|
*
|
|
* $RCSfile: vrmp.s $
|
|
* $Revision: 1.5 $
|
|
* $Date: 1996/06/20 16:30:16 $
|
|
* $Locker: $
|
|
*/
|
|
|
|
#include "VrBAT.h"
|
|
|
|
/*
|
|
* The PPC Open Firmware implementation uses a different protocol
|
|
* for MP startup than the ARC specification. In this module,
|
|
* we implement the ARC startup protocol.
|
|
*
|
|
* The PPC OF binding specifies that the /cpus node has
|
|
* a method cpu-machine-execute ( addr cpu# -- true | false )
|
|
* where cpu# is the cpu number and addr is the address
|
|
* (in the parent's address space?) at which the cpu is to
|
|
* begin execution.
|
|
*
|
|
* The ARC specifies that a cpu is to spin on the state of the
|
|
* ProcessorStart bit in the BootStatus word of the cpu's Restart Block.
|
|
* When ProcessorStart = 1, the cpu switches context to that saved in
|
|
* the SaveArea array in the Restart Block.
|
|
*
|
|
* Define here the context switch routine and the polling loop.
|
|
*/
|
|
.data
|
|
.align 4
|
|
.globl naperr
|
|
naperr:
|
|
.ascii "processor not sleeping"
|
|
|
|
.text
|
|
.align 4
|
|
.globl ..fatal
|
|
|
|
/*
|
|
* VOID ArcPoll(VOID)
|
|
*/
|
|
.globl ArcPoll
|
|
ArcPoll:
|
|
/*
|
|
* We have to figure out where our BootStatus and SaveArea are.
|
|
* There's no way to explicitly pass variables to this routine,
|
|
* so our caller has helpfully stuffed them into locations
|
|
* ArcPoll-8 and ArcPoll-4. Retrieve them into r3 and r4.
|
|
* The pvr is initialized in ArcPoll-12. This is used by
|
|
* the IdleCPU() to check whether the machine is Multi processor
|
|
* worthy or not. The pvr should match for all proceesors and
|
|
* rev > 3.4 to be MP worthy
|
|
* Incidentally, we can trash all our registers as we won't
|
|
* ever return from this loop and this routine is not TOC-based.
|
|
*/
|
|
|
|
bl here
|
|
here:
|
|
mfpvr r5
|
|
mflr r1 // r1 = here
|
|
mr r4, r1
|
|
stw r5, -16(r1) // store it before moving 0x1234
|
|
li r2, 0x1234
|
|
lwz r3, -12(r1)
|
|
stw r2, -12(r1)
|
|
mr r29, r1 // save off r1 for future use
|
|
lwz r1, -8(r1)
|
|
|
|
cputest:
|
|
lwz r5, -12(r29)
|
|
cmplw r5, r2 // is still 1234
|
|
beq cputest
|
|
li r2, 0xBAD
|
|
cmplw r5, r2 // is it bad to start this cpu
|
|
bne gonow
|
|
napnow: // put it to sleep
|
|
mfmsr r5
|
|
li r2, 4
|
|
rlwinm r2,r2,16,0,31
|
|
or r5,r5,r2
|
|
mtmsr r5
|
|
// lis r3, (naperr>>16)
|
|
// ori r3, r3, napper
|
|
b ..fatal
|
|
|
|
gonow:
|
|
//
|
|
// Turn off data/address translation ( I.E. go to real mode )
|
|
//
|
|
bl RealMode
|
|
|
|
/*
|
|
* Spin on the ProcessorStart bit (bit 23 in PPC nomenclature).
|
|
*/
|
|
ArcSpin:
|
|
lwz r2, 0(r3)
|
|
extrwi. r2, r2, 1, 23
|
|
beq ArcSpin
|
|
|
|
/*
|
|
* ProcessorStart is 1: reload processor state.
|
|
*/
|
|
li r2, 0x789a
|
|
stw r2, -12(r4)
|
|
|
|
lwz r2, 0x104(r1) // CR0-7
|
|
mtcrf 255, r2
|
|
lwz r2, 0x108(r1) // XER
|
|
mtxer r2
|
|
lwz r2, 0x110(r1) // IAR
|
|
lis r3, 0x8000
|
|
andc r2, r2, r3
|
|
mtlr r2
|
|
|
|
lwz r0, 0x84(r1)
|
|
// Get r1 later.
|
|
lwz r2, 0x8c(r1)
|
|
lwz r3, 0x90(r1)
|
|
lwz r4, 0x94(r1)
|
|
lwz r5, 0x98(r1)
|
|
lwz r6, 0x9c(r1)
|
|
lwz r7, 0xa0(r1)
|
|
lwz r8, 0xa4(r1)
|
|
lwz r9, 0xa8(r1)
|
|
lwz r10, 0xac(r1)
|
|
lwz r11, 0xb0(r1)
|
|
lwz r12, 0xb4(r1)
|
|
lwz r13, 0xb8(r1)
|
|
lwz r14, 0xbc(r1)
|
|
lwz r15, 0xc0(r1)
|
|
lwz r16, 0xc4(r1)
|
|
lwz r17, 0xc8(r1)
|
|
lwz r18, 0xcc(r1)
|
|
lwz r19, 0xd0(r1)
|
|
lwz r20, 0xd4(r1)
|
|
lwz r21, 0xd8(r1)
|
|
lwz r22, 0xdc(r1)
|
|
lwz r23, 0xe0(r1)
|
|
lwz r24, 0xe4(r1)
|
|
lwz r25, 0xe8(r1)
|
|
lwz r26, 0xec(r1)
|
|
lwz r27, 0xf0(r1)
|
|
lwz r28, 0xf4(r1)
|
|
lwz r29, 0xf8(r1)
|
|
lwz r30, 0xfc(r1)
|
|
lwz r31,0x100(r1)
|
|
|
|
lwz r1, 0x88(r1)
|
|
blr
|
|
|
|
|
|
/*
|
|
* Goto real mode via a branch and link to this routine. We'll turn off
|
|
* data and instruction address translation and reset the program counter
|
|
* so the return from this routine leaves the cpu in real mode.
|
|
*/
|
|
.globl RealMode
|
|
RealMode:
|
|
mflr r20
|
|
mfmsr r21 // get current state
|
|
rlwinm r21, r21, 0, ~EXTRNL_INT_ENABL // clear interrupt enable
|
|
mtmsr r21 // disable interrupts
|
|
rlwinm r21, r21, 0, ~(DATA_ADDR_XLATE | INSTR_ADDR_XLATE )
|
|
mtsrr1 r21 // desired initial state
|
|
rlwinm r20, r20, 0, 0x7fffffff // physical return addrress
|
|
mtsrr0 r20
|
|
rfi // return
|
|
|
|
.globl EndArcPoll
|
|
EndArcPoll:
|