File: bare.S

package info (click to toggle)
kernel-source-2.0.32 2.0.32-5
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 29,648 kB
  • ctags: 86,850
  • sloc: ansic: 542,141; asm: 26,201; makefile: 3,423; sh: 1,195; perl: 727; tcl: 408; cpp: 277; lisp: 211; awk: 134
file content (160 lines) | stat: -rw-r--r-- 3,445 bytes parent folder | download | duplicates (7)
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
/* $Id: bare.S,v 1.4 1996/04/23 01:53:40 davem Exp $
 * base.S:      Ugly low-level boot program entry code.  The job of this
 *              module is to parse the boot flags, try to mount the remote
 *              root filesystem and load the kernel into virtual memory.
 *
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 */

#include "bare.h"
#include <asm/ptrace.h>

	.data
	.globl C_LABEL(romvec)
	.globl C_LABEL(idp_ptr)

C_LABEL(romvec):
	.word 0
C_LABEL(idp_ptr):
	.word 0

	.text
	.align 8
	.globl C_LABEL(first_adr_in_text)

C_LABEL(first_adr_in_text):

	/* Grrr, boot block, scratching my head... */
	.globl C_LABEL(b_block)       /* Start of actual boot block */
	.globl C_LABEL(b_block_size)  /* In bytes */
	.globl C_LABEL(b_block_cksum) /* Checksum of boot block bytes */

	b	start_of_execution    /* XXX Hack */
	nop

	.align	8
C_LABEL(b_block):	
	.skip	(BOOTBLOCK_NENTRIES * BOOTBLOCK_ENTSIZE)

C_LABEL(b_block_size):
	.word	0

C_LABEL(b_block_cksum):
	.word	0

/* Ok, the prom has left in %o0 the PROM pointer.  We leave it here
 * for when we jump into the kernel.  So save out of this window before
 * you dick with %o0.  As far as I know we could be loaded *anywhere*, so
 * we relocate ourselves to the "linked" location.  Self modifying code rules.
 */

start_of_execution:
	sethi	%hi(C_LABEL(first_adr_in_text)), %o1		! This is our top
	or	%o1, %lo(C_LABEL(first_adr_in_text)), %o1	! of stack too.
	sub	%o1, REGWIN_SZ, %o1
	add	%o1, 0x7, %o1
	andn	%o1, 0x7, %o1
	save	%o1, 0x0, %sp					! save is an add
here:
	call	there
	sethi	%hi(here), %o4
there:	
	sub	%o7, here-C_LABEL(first_adr_in_text), %o5
	or	%o4, %lo(here), %o4
	cmp	%o4, %o7
	be	loaded_ok
	nop

	/* Gotta relocate, compute our size sans bss segment. */
	set	C_LABEL(edata)+4, %o3
	set	C_LABEL(first_adr_in_text), %o2
	sub	%o3, %o2, %o3
rel_loop:
	ld	[%o5], %o4
	add	%o5, 0x4, %o5
	st	%o4, [%o2]
	subcc	%o3, 0x4, %o3
	bg	rel_loop
	add	%o2, 0x4, %o2

	/* Pray that we are now in a sane place in memory */
	sethi	%hi(loaded_ok), %o2
	or	%o2, %lo(loaded_ok), %o2
	jmp	%o2
	nop

loaded_ok:
	/* Save the PROM pointer */
	sethi	%hi(C_LABEL(romvec)), %o1
	or	%o1, %lo(C_LABEL(romvec)), %o1
	st	%i0, [%o1]

	/* Build a PSR we can live with */
	rd	%psr, %o1

#if 0
	andn	%o1, PSR_PIL, %o1
	sethi	%hi(SANE_PSR), %g4
	or	%g4, %lo(SANE_PSR), %g4
	or	%o1, %g4, %o1
#endif

	/* V8 book says this works to calculate num_windows */
	sethi	%hi(0xffffffff), %g2
	rd	%wim, %g3
	or	%g2, %lo(0xffffffff), %g2
	wr	%g2, 0x0, %wim
	WRITE_PAUSE

	rd	%wim, %g4
	WRITE_PAUSE

	wr	%g3, 0x0, %wim
	WRITE_PAUSE

	/* Restore old %psr */
	wr	%o1, 0x0, %psr
	WRITE_PAUSE

	or	%g0, 0x0, %g3
1:
	srl	%g4, 0x1, %g4
	subcc	%g4, 0x0, %g0
	bne	1b
	add	%g3, 0x1, %g3
	
	/* %g3 now contains nwindows */
	sethi	%hi(C_LABEL(nwindows)), %o4
	st	%g3, [%o4 + %lo(C_LABEL(nwindows))]

	/* Now zero out our bss segment, lord knows the nasty prom monster
	 * didn't do it for us.
	 */
	sethi	%hi(C_LABEL(end)), %g1
	or	%g1, %lo(C_LABEL(end)), %g1
	add	%g1, 0x4, %g1
	sethi	%hi(C_LABEL(edata)), %g2
	or	%g2, %lo(C_LABEL(edata)), %g2

	/* Slow, inefficient, who cares, this is messy boot code */
bzero_bss_loop:
	st	%g0, [%g2]
	add	%g2, 0x4, %g2
	cmp	%g2, %g1
	bl	bzero_bss_loop
	nop

	call	C_LABEL(init_me)	! Fun with empirical constants and prom
	nop

	/* Dump back into the prom */
get_me_out_of_here:
	set	C_LABEL(romvec), %g2
	ld	[%g2], %g2
	ld	[%g2 + 0x74], %g2
	restore
	call	%g2
	nop