summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/shared/start/start.S
blob: ee09686659bddf1370046181320b164b7df2312f (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
172
173
174
175
176
177
178
179
180
181
182
183
/*
 *  start.S :	  RTEMS entry point
 *
 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
 *
 *  The license and distribution terms for this file may be
 *  found in found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 *
 */

#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include <rtems/score/cpu.h>
#include "asm.h"

#define SYNC \
	sync; \
	isync

#define KERNELBASE	0x0

#define MONITOR_ENTER			\
	mfmsr	r10		;	\
	ori	r10,r10,MSR_IP	;	\
	mtmsr	r10		;	\
	li	r10,0x63	;	\
	sc
			
	.text
	.globl	__rtems_entry_point
	.type	__rtems_entry_point,@function
__rtems_entry_point:
#ifdef DEBUG_EARLY_START
	MONITOR_ENTER
#endif	
		
/* 
 * PREP
 * This is jumped to on prep systems right after the kernel is relocated
 * to its proper place in memory by the boot loader.  The expected layout
 * of the regs is:	
 *   r3: ptr to residual data
 *   r4: initrd_start or if no initrd then 0
 *   r5: initrd_end - unused if r4 is 0
 *   r6: Start of command line string
 *   r7: End of command line string
 *
 *   The Prep boot loader insure that the MMU is currently off...
 *
 */
	
	mr	r31,r3			/* save parameters */
	mr	r30,r4
	mr	r29,r5
	mr	r28,r6
	mr	r27,r7
	/*
	 * Make sure we have nothing in BATS and TLB
	 */
	bl	clear_bats
	bl	flush_tlbs
/*
 * Use the first pair of BAT registers to map the 1st 64MB
 * of RAM to KERNELBASE. 
 */
	lis	r11,KERNELBASE@h
	ori	r11,r11,0x7fe		/* set up BAT registers for 604 */
	li	r8,2			/* R/W access */
	isync
	mtspr	DBAT0L,r8		/* N.B. 6xx (not 601) have valid */
	mtspr	DBAT0U,r11		/* bit in upper BAT register */
	mtspr	IBAT0L,r8
	mtspr	IBAT0U,r11
	isync

/*
 * we now have the 1st 64M of ram mapped with the bats.
 */
	
enter_C_code:
	bl	MMUon
	/*
	 * stack = &__rtems_end + 4096
	 */
	addis	r9,r0, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@ha
        addi	r9,r9, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@l
	mr	r1, r9
	bl	zero_bss
	/*
	 * restore prep boot params
	 */
	mr	r3,r31
	mr	r4,r30
	mr	r5,r29
	mr	r6,r28
	mr	r7,r27 
	bl	save_boot_params
	bl	boot_card
	bl	_return_to_ppcbug
	
	.globl  MMUon
	.type	MMUon,@function
MMUon:	
	mfmsr	r0
	ori	r0,r0, MSR_IP | MSR_RI | MSR_IR | MSR_DR | MSR_EE | MSR_FE0 | MSR_FE1
	xori	r0, r0, MSR_EE | MSR_IP | MSR_FP
	mflr	r11
	mtsrr0	r11
	mtsrr1	r0
	SYNC
	rfi
	
	.globl  MMUoff
	.type	MMUoff,@function
MMUoff:	
	mfmsr	r0
	ori	r0,r0,MSR_IR| MSR_DR | MSR_IP
	mflr	r11
	xori	r0,r0,MSR_IR|MSR_DR
	mtsrr0	r11
	mtsrr1	r0
	SYNC
	rfi

	.globl	_return_to_ppcbug
	.type	_return_to_ppcbug,@function

	
_return_to_ppcbug:
	mflr	r30
	bl	MMUoff
	MONITOR_ENTER
	bl	MMUon
	mtctr	r30
	bctr	

/* 
 * An undocumented "feature" of 604e requires that the v bit
 * be cleared before changing BAT values.
 *
 * Also, newer IBM firmware does not clear bat3 and 4 so
 * this makes sure it's done.
 *  -- Cort 
 */
clear_bats:
	li	r20,0
	mfspr	r9,PVR
	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
	cmpwi	r9, 1
	SYNC
	beq	1f
	mtspr	DBAT0U,r20
	mtspr	DBAT0L,r20	
	mtspr	DBAT1U,r20
	mtspr	DBAT1L,r20
	mtspr	DBAT2U,r20
	mtspr	DBAT2L,r20	
	mtspr	DBAT3U,r20
	mtspr	DBAT3L,r20
1:	
	mtspr	IBAT0U,r20
	mtspr	IBAT0L,r20
	mtspr	IBAT1U,r20
	mtspr	IBAT1L,r20
	mtspr	IBAT2U,r20
	mtspr	IBAT2L,r20
	mtspr	IBAT3U,r20
	mtspr	IBAT3L,r20
	SYNC	
	blr

flush_tlbs:
	lis	r20, 0x1000
1:	addic.	r20, r20, -0x1000
	tlbie	r20
	blt	1b
	sync
	blr