summaryrefslogtreecommitdiff
path: root/src/arch/ppc/init/crt0.S.lb
blob: 738d4b4a67f3fc8f1c2a6810affcf8f5c2d81420 (plain)
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
/* Copyright 2000  AG Electronics Ltd. */
/* This code is distributed without warranty under the GPL v2 (see COPYING) */

#define ASM
#include "ppcreg.h"
#include <ppc_asm.tmpl>

.section ".rom.reset", "ax", @progbits

.globl _start
_start:
	b	system_reset

.section ".rom.exception_vectors", "ax", @progbits

%%EXCEPTION_VECTOR_TABLE%%

.section ".rom.data", "a", @progbits
.section ".rom.text", "ax", @progbits

system_reset:

	/*
	 * Do processor family initialization
	 */
%%FAMILY_INIT%%

	/*
	 * Do processor specific initialization
	 */
%%PROCESSOR_INIT%%

#if USE_DCACHE_RAM == 1
#define DCACHE_RAM_END	(DCACHE_RAM_BASE + DCACHE_RAM_SIZE - 1)
	/*
	 * Initialize data cache blocks 
	 * (assumes cache block size of 32 bytes)
	 *
	 * NOTE: This may need to be moved to FAMILY_INIT if
	 *       dcbz is not supported on all CPU's
	 */
	lis     r1, DCACHE_RAM_BASE@h
	ori     r1, r1, DCACHE_RAM_BASE@l
	li      r3, (DCACHE_RAM_SIZE / 32)
	mtctr   r3
0:      dcbz    r0, r1
	addi    r1, r1, 32
	bdnz    0b

	/*
	 * Set up stack in cache. The SP must be 16-byte (4-word) aligned
	 * for SYSV EABI or 8-byte (2-word) aligned for PPC EABI, so we make 
	 * it 16-byte aligned to cover both cases. Also we have to ensure that
	 * the first word is located within the cache.
	 */
	lis     r1, (DCACHE_RAM_BASE+DCACHE_RAM_SIZE)@h
	ori     r1, r1, (DCACHE_RAM_BASE+DCACHE_RAM_SIZE)@l
	lis	r0, 0
	stwu	r0, -4(r1)
	stwu	r0, -4(r1)
	stwu	r0, -4(r1)
	stwu	r0, -4(r1)

#if 0
	/*
	 * Clear stack
	 */
	lis	r4, DCACHE_RAM_BASE@h
	ori	r4, r4, DCACHE_RAM_BASE@l
	lis	r7, DCACHE_RAM_END@h
	ori	r7, r7, DCACHE_RAM_END@l
	lis	r5, 0
1:	stwx	r5, 0, r4
	addi	r4, r4, 4
	cmp	0, 0, r4, r7
	ble	1b
	sync
#endif

	/*
	 * Set up the EABI pointers, before we enter any C code
	 */
	lis     r13, _SDA_BASE_@h
	ori     r13, r13, _SDA_BASE_@l
	lis     r2, _SDA2_BASE_@h
	ori     r2, r2, _SDA2_BASE_@l

	/*
	 * load start address into SRR0 for rfi
	 */
	lis	r3, ppc_main@h
	ori 	r3, r3, ppc_main@l
	mtspr	SRR0, r3

	/*
	 * load the current MSR into SRR1 so that it will be copied 
	 * back into MSR on rfi
	 */
	mfmsr	r4
	mtspr	SRR1, r4	// load SRR1 with r4

	/*
	 * If something returns after rfi then die
	 */
	lis	r3, dead@h
	ori	r3, r3, dead@l
	mtlr	r3

	/*
	 * Complete rest of initialization in C (ppc_main)
	 */
	rfi
#endif /* USE_DCACHE_RAM */

	/*
	 * Stop here if something goes wrong
	 */
dead:
	b	dead
	/*NOTREACHED*/

/* Remove need for ecrti.o and ectrn.o */
.globl __init
__init:
.globl __fini
__fini:
.globl __CTOR_LIST__
__CTOR_LIST__:
.globl __CTOR_END__
__CTOR_END__:
.globl __DTOR_LIST__
__DTOR_LIST__:
.globl __DTOR_END__
__DTOR_END__:
        blr

%%NORTHBRIDGE_INIT%%