summaryrefslogtreecommitdiffstats
path: root/private/ntos/boot/veneer/ppc/vrmp.s
blob: f47b798c29be87d9d9ef4751003cf2fcefa3be8b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * 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: