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
|
/*
* This is based on the mvme-crt0.S file from libgloss/rs6000.
* crt0.S -- startup file for PowerPC systems.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*
* $Id$
*/
#include "ppc-asm.h"
.file "start.S"
.section ".got2","aw"
.align 2
.LCTOC1 = .+32768
.extern FUNC_NAME(atexit)
.globl FUNC_NAME(__atexit)
.section ".sdata","aw"
.align 2
FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
.long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
.section ".fixup","aw"
.align 2
.long FUNC_NAME(__atexit)
.section ".got2","aw"
.Ltable = .-.LCTOC1
.long .LCTOC1 /* address we think .LCTOC1 is loaded at */
.Lbss_start = .-.LCTOC1
.long __sbss_start /* need to include sbss and bss sections */
.Lend = .-.LCTOC1
.long _end
.Lstack = .-.LCTOC1 /* stack address if set by user */
.long __stack
.Ltext_start = .-.LCTOC1 /* beginning of text segment */
.long __text_start
.text
/* PPCBUG ROM bootstrap record */
.ascii "BOOT" /* "magic number" */
.long 0x10 /* offset to first instruction */
.long 0x16 /* length of record, including checksum */
.ascii "BOOT" /* routine name */
b _start /* code of routine */
.short 0x6b79 /* checksum */
.short 0x0000 /* space filler */
.Lptr:
.long .LCTOC1-.Laddr
.globl _start
.type _start,@function
_start:
bl .Laddr /* get current address */
.Laddr:
mflr r4 /* real address of .Laddr */
lwz r5,(.Lptr-.Laddr)(r4) /* linker generated address of .LCTOC1 */
add r5,r5,r4 /* correct to real pointer */
lwz r4,.Ltable(r5) /* get linker's idea of where .Laddr is */
subf r4,r4,r5 /* calculate difference between where linked and current */
/* copy text and data to RAM */
lwz r6,.Ltext_start(r5) /* calculate beginning of the text */
lwz r7,.Lbss_start(r5) /* calculate end of the init data */
cmplw 1,r6,r7
bc 4,4,.Ldone1
subf r8,r6,r7 /* number of bytes to copy */
addi r8,r8,3 /* round up to next word boundary */
srwi r9,r8,2 /* number of words to copy */
mtctr r9
addi r6,r6,-4 /* adjust so we can use stwu */
add r8,r6,r4 /* get source address in ROM */
.Lloop1:
lwzu r0,4(r8) /* load word from ROM */
stwu r0,4(r6) /* store word to RAM */
bdnz .Lloop1
.Ldone1:
/* clear bss */
lwz r6,.Lbss_start(r5) /* calculate beginning of the BSS */
lwz r7,.Lend(r5) /* calculate end of the BSS */
cmplw 1,r6,r7
bc 4,4,.Ldone
subf r8,r6,r7 /* number of bytes to zero */
srwi r9,r8,2 /* number of words to zero */
mtctr r9
li r0,0 /* zero to clear memory */
addi r6,r6,-4 /* adjust so we can use stwu */
.Lloop:
stwu r0,4(r6) /* zero bss */
bdnz .Lloop
.Ldone:
lwz r0,.Lstack(r5) /* stack address or 0 */
cmplwi 1,r0,0 /* equal to 0? */
bc 12,6,.Lnostack /* use default stack if == 0 */
mr sp,r0 /* use user defined stack */
.Lnostack:
/* set up initial stack frame */
addi sp,sp,-4 /* make sure we don't overwrite debug mem */
lis r0,0
stw r0,0(sp) /* clear back chain */
stwu sp,-56(sp) /* push another stack frame */
/* jump to RAM and continue */
ba .Lcontinue
.Lcontinue:
/* invalidate instruction cache */
mfspr r4,1008 /* read hid0 */
ori r5,r4,0x00000800 /* set icfi bit */
mtspr 1008,r5
sync
isync
mtspr 1008,r4 /* restore hid0 */
sync
isync
/* Let her rip */
bl FUNC_NAME(boot_card)
/* return value from boot_card is argument to exit */
bl FUNC_NAME(exit)
trap
.Lstart:
.size _start,.Lstart-_start
|