aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/prom
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-09-22 23:11:33 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-09-22 23:11:33 -0400
commitbff06d552240ba7f5b49482a4865871d7bc03dc2 (patch)
treeee760e252023bec338921296b12bb54987bedcac /arch/sparc64/prom
parent40fd3533c93f0062b6d1d8540961ef70fc8ab750 (diff)
[SPARC64]: Rewrite bootup sequence.
Instead of all of this cpu-specific code to remap the kernel to the correct location, use portable firmware calls to do this instead. What we do now is the following in position independant assembler: chosen_node = prom_finddevice("/chosen"); prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu"); vaddr = 4MB_ALIGN(current_text_addr()); prom_translate(vaddr, &paddr_high, &paddr_low, &mode); prom_boot_mapping_mode = mode; prom_boot_mapping_phys_high = paddr_high; prom_boot_mapping_phys_low = paddr_low; prom_map(-1, 8 * 1024 * 1024, KERNBASE, paddr_low); and that replaces the massive amount of by-hand TLB probing and programming we used to do here. The new code should also handle properly the case where the kernel is mapped at the correct address already (think: future kexec support). Consequently, the bulk of remap_kernel() dies as does the entirety of arch/sparc64/prom/map.S We try to share some strings in the PROM library with the ones used at bootup, and while we're here mark input strings to oplib.h routines with "const" when appropriate. There are many more simplifications now possible. For one thing, we can consolidate the two copies we now have of a lot of cpu setup code sitting in head.S and trampoline.S. This is a significant step towards CONFIG_DEBUG_PAGEALLOC support. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/prom')
-rw-r--r--arch/sparc64/prom/Makefile2
-rw-r--r--arch/sparc64/prom/console.c2
-rw-r--r--arch/sparc64/prom/devops.c2
-rw-r--r--arch/sparc64/prom/init.c2
-rw-r--r--arch/sparc64/prom/map.S72
-rw-r--r--arch/sparc64/prom/misc.c34
-rw-r--r--arch/sparc64/prom/p1275.c2
-rw-r--r--arch/sparc64/prom/printf.c2
-rw-r--r--arch/sparc64/prom/tree.c50
9 files changed, 48 insertions, 120 deletions
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
index 8f2420d9e9e6..c7898a5ee456 100644
--- a/arch/sparc64/prom/Makefile
+++ b/arch/sparc64/prom/Makefile
@@ -7,4 +7,4 @@ EXTRA_AFLAGS := -ansi
7EXTRA_CFLAGS := -Werror 7EXTRA_CFLAGS := -Werror
8 8
9lib-y := bootstr.o devops.o init.o memory.o misc.o \ 9lib-y := bootstr.o devops.o init.o memory.o misc.o \
10 tree.o console.o printf.o p1275.o map.o cif.o 10 tree.o console.o printf.o p1275.o cif.o
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index 028a53fcb1ec..eae5db8dda56 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -67,7 +67,7 @@ prom_putchar(char c)
67} 67}
68 68
69void 69void
70prom_puts(char *s, int len) 70prom_puts(const char *s, int len)
71{ 71{
72 p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| 72 p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
73 P1275_INOUT(3,1), 73 P1275_INOUT(3,1),
diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c
index 2c99b21b6981..4641839eb39a 100644
--- a/arch/sparc64/prom/devops.c
+++ b/arch/sparc64/prom/devops.c
@@ -16,7 +16,7 @@
16 * Returns 0 on failure. 16 * Returns 0 on failure.
17 */ 17 */
18int 18int
19prom_devopen(char *dstr) 19prom_devopen(const char *dstr)
20{ 20{
21 return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| 21 return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
22 P1275_INOUT(1,1), 22 P1275_INOUT(1,1),
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
index 817faae058cd..8b4b622d0909 100644
--- a/arch/sparc64/prom/init.c
+++ b/arch/sparc64/prom/init.c
@@ -46,7 +46,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
46 if((prom_root_node == 0) || (prom_root_node == -1)) 46 if((prom_root_node == 0) || (prom_root_node == -1))
47 prom_halt(); 47 prom_halt();
48 48
49 prom_chosen_node = prom_finddevice("/chosen"); 49 prom_chosen_node = prom_finddevice(prom_chosen_path);
50 if (!prom_chosen_node || prom_chosen_node == -1) 50 if (!prom_chosen_node || prom_chosen_node == -1)
51 prom_halt(); 51 prom_halt();
52 52
diff --git a/arch/sparc64/prom/map.S b/arch/sparc64/prom/map.S
deleted file mode 100644
index 21b3f9c99ea7..000000000000
--- a/arch/sparc64/prom/map.S
+++ /dev/null
@@ -1,72 +0,0 @@
1/* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $
2 * map.S: Tricky coding required to fixup the kernel OBP maps
3 * properly.
4 *
5 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
6 */
7
8 .text
9 .align 8192
10 .globl prom_boot_page
11prom_boot_page:
12call_method:
13 .asciz "call-method"
14 .align 8
15map:
16 .asciz "map"
17 .align 8
18
19 /* When we are invoked, our caller has remapped us to
20 * page zero, therefore we must use PC relative addressing
21 * for everything after we begin performing the unmap/map
22 * calls.
23 */
24 .globl prom_remap
25prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */
26 rd %pc, %g1
27 srl %o2, 0, %o2 ! kill sign extension
28 sethi %hi(p1275buf), %g2
29 or %g2, %lo(p1275buf), %g2
30 ldx [%g2 + 0x10], %g3 ! prom_cif_stack
31 save %g3, -(192 + 128), %sp
32 ldx [%g2 + 0x08], %l0 ! prom_cif_handler
33 mov %g6, %i3
34 mov %g4, %i4
35 mov %g5, %i5
36 flushw
37
38 sethi %hi(prom_remap - call_method), %g7
39 or %g7, %lo(prom_remap - call_method), %g7
40 sub %g1, %g7, %l2 ! call-method string
41 sethi %hi(prom_remap - map), %g7
42 or %g7, %lo(prom_remap - map), %g7
43 sub %g1, %g7, %l4 ! map string
44
45 /* OK, map the 4MB region we really live at. */
46 stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method
47 mov 7, %l5
48 stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args
49 mov 1, %l5
50 stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets
51 stx %l4, [%sp + 2047 + 128 + 0x18] ! map
52 stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle
53 mov -1, %l5
54 stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default
55 sethi %hi(4 * 1024 * 1024), %l5
56 stx %l5, [%sp + 2047 + 128 + 0x30] ! size
57 stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr
58 stx %g0, [%sp + 2047 + 128 + 0x40] ! filler
59 stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr
60 call %l0
61 add %sp, (2047 + 128), %o0 ! argument array
62
63 /* Restore hard-coded globals. */
64 mov %i3, %g6
65 mov %i4, %g4
66 mov %i5, %g5
67
68 /* Wheee.... we are done. */
69 ret
70 restore
71
72 .align 8192
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 19c44e97e9ee..9b895faf077b 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -17,14 +17,14 @@
17#include <asm/system.h> 17#include <asm/system.h>
18 18
19/* Reset and reboot the machine with the command 'bcommand'. */ 19/* Reset and reboot the machine with the command 'bcommand'. */
20void prom_reboot(char *bcommand) 20void prom_reboot(const char *bcommand)
21{ 21{
22 p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | 22 p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
23 P1275_INOUT(1, 0), bcommand); 23 P1275_INOUT(1, 0), bcommand);
24} 24}
25 25
26/* Forth evaluate the expression contained in 'fstring'. */ 26/* Forth evaluate the expression contained in 'fstring'. */
27void prom_feval(char *fstring) 27void prom_feval(const char *fstring)
28{ 28{
29 if (!fstring || fstring[0] == 0) 29 if (!fstring || fstring[0] == 0)
30 return; 30 return;
@@ -148,21 +148,19 @@ void prom_set_trap_table(unsigned long tba)
148 p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); 148 p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba);
149} 149}
150 150
151int mmu_ihandle_cache = 0;
152
153int prom_get_mmu_ihandle(void) 151int prom_get_mmu_ihandle(void)
154{ 152{
155 int node, ret; 153 int node, ret;
156 154
157 if (mmu_ihandle_cache != 0) 155 if (prom_mmu_ihandle_cache != 0)
158 return mmu_ihandle_cache; 156 return prom_mmu_ihandle_cache;
159 157
160 node = prom_finddevice("/chosen"); 158 node = prom_finddevice(prom_chosen_path);
161 ret = prom_getint(node, "mmu"); 159 ret = prom_getint(node, prom_mmu_name);
162 if (ret == -1 || ret == 0) 160 if (ret == -1 || ret == 0)
163 mmu_ihandle_cache = -1; 161 prom_mmu_ihandle_cache = -1;
164 else 162 else
165 mmu_ihandle_cache = ret; 163 prom_mmu_ihandle_cache = ret;
166 164
167 return ret; 165 return ret;
168} 166}
@@ -190,7 +188,7 @@ long prom_itlb_load(unsigned long index,
190 unsigned long tte_data, 188 unsigned long tte_data,
191 unsigned long vaddr) 189 unsigned long vaddr)
192{ 190{
193 return p1275_cmd("call-method", 191 return p1275_cmd(prom_callmethod_name,
194 (P1275_ARG(0, P1275_ARG_IN_STRING) | 192 (P1275_ARG(0, P1275_ARG_IN_STRING) |
195 P1275_ARG(2, P1275_ARG_IN_64B) | 193 P1275_ARG(2, P1275_ARG_IN_64B) |
196 P1275_ARG(3, P1275_ARG_IN_64B) | 194 P1275_ARG(3, P1275_ARG_IN_64B) |
@@ -207,7 +205,7 @@ long prom_dtlb_load(unsigned long index,
207 unsigned long tte_data, 205 unsigned long tte_data,
208 unsigned long vaddr) 206 unsigned long vaddr)
209{ 207{
210 return p1275_cmd("call-method", 208 return p1275_cmd(prom_callmethod_name,
211 (P1275_ARG(0, P1275_ARG_IN_STRING) | 209 (P1275_ARG(0, P1275_ARG_IN_STRING) |
212 P1275_ARG(2, P1275_ARG_IN_64B) | 210 P1275_ARG(2, P1275_ARG_IN_64B) |
213 P1275_ARG(3, P1275_ARG_IN_64B) | 211 P1275_ARG(3, P1275_ARG_IN_64B) |
@@ -223,13 +221,13 @@ long prom_dtlb_load(unsigned long index,
223int prom_map(int mode, unsigned long size, 221int prom_map(int mode, unsigned long size,
224 unsigned long vaddr, unsigned long paddr) 222 unsigned long vaddr, unsigned long paddr)
225{ 223{
226 int ret = p1275_cmd("call-method", 224 int ret = p1275_cmd(prom_callmethod_name,
227 (P1275_ARG(0, P1275_ARG_IN_STRING) | 225 (P1275_ARG(0, P1275_ARG_IN_STRING) |
228 P1275_ARG(3, P1275_ARG_IN_64B) | 226 P1275_ARG(3, P1275_ARG_IN_64B) |
229 P1275_ARG(4, P1275_ARG_IN_64B) | 227 P1275_ARG(4, P1275_ARG_IN_64B) |
230 P1275_ARG(6, P1275_ARG_IN_64B) | 228 P1275_ARG(6, P1275_ARG_IN_64B) |
231 P1275_INOUT(7, 1)), 229 P1275_INOUT(7, 1)),
232 "map", 230 prom_map_name,
233 prom_get_mmu_ihandle(), 231 prom_get_mmu_ihandle(),
234 mode, 232 mode,
235 size, 233 size,
@@ -244,12 +242,12 @@ int prom_map(int mode, unsigned long size,
244 242
245void prom_unmap(unsigned long size, unsigned long vaddr) 243void prom_unmap(unsigned long size, unsigned long vaddr)
246{ 244{
247 p1275_cmd("call-method", 245 p1275_cmd(prom_callmethod_name,
248 (P1275_ARG(0, P1275_ARG_IN_STRING) | 246 (P1275_ARG(0, P1275_ARG_IN_STRING) |
249 P1275_ARG(2, P1275_ARG_IN_64B) | 247 P1275_ARG(2, P1275_ARG_IN_64B) |
250 P1275_ARG(3, P1275_ARG_IN_64B) | 248 P1275_ARG(3, P1275_ARG_IN_64B) |
251 P1275_INOUT(4, 0)), 249 P1275_INOUT(4, 0)),
252 "unmap", 250 prom_unmap_name,
253 prom_get_mmu_ihandle(), 251 prom_get_mmu_ihandle(),
254 size, 252 size,
255 vaddr); 253 vaddr);
@@ -258,7 +256,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr)
258/* Set aside physical memory which is not touched or modified 256/* Set aside physical memory which is not touched or modified
259 * across soft resets. 257 * across soft resets.
260 */ 258 */
261unsigned long prom_retain(char *name, 259unsigned long prom_retain(const char *name,
262 unsigned long pa_low, unsigned long pa_high, 260 unsigned long pa_low, unsigned long pa_high,
263 long size, long align) 261 long size, long align)
264{ 262{
@@ -290,7 +288,7 @@ int prom_getunumber(int syndrome_code,
290 unsigned long phys_addr, 288 unsigned long phys_addr,
291 char *buf, int buflen) 289 char *buf, int buflen)
292{ 290{
293 return p1275_cmd("call-method", 291 return p1275_cmd(prom_callmethod_name,
294 (P1275_ARG(0, P1275_ARG_IN_STRING) | 292 (P1275_ARG(0, P1275_ARG_IN_STRING) |
295 P1275_ARG(3, P1275_ARG_OUT_BUF) | 293 P1275_ARG(3, P1275_ARG_OUT_BUF) |
296 P1275_ARG(6, P1275_ARG_IN_64B) | 294 P1275_ARG(6, P1275_ARG_IN_64B) |
diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c
index 59fe38bba39e..a5a7c5712028 100644
--- a/arch/sparc64/prom/p1275.c
+++ b/arch/sparc64/prom/p1275.c
@@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void)
46 */ 46 */
47DEFINE_SPINLOCK(prom_entry_lock); 47DEFINE_SPINLOCK(prom_entry_lock);
48 48
49long p1275_cmd (char *service, long fmt, ...) 49long p1275_cmd(const char *service, long fmt, ...)
50{ 50{
51 char *p, *q; 51 char *p, *q;
52 unsigned long flags; 52 unsigned long flags;
diff --git a/arch/sparc64/prom/printf.c b/arch/sparc64/prom/printf.c
index a6df82cafa0d..660943ee4c2a 100644
--- a/arch/sparc64/prom/printf.c
+++ b/arch/sparc64/prom/printf.c
@@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n)
34} 34}
35 35
36void 36void
37prom_printf(char *fmt, ...) 37prom_printf(const char *fmt, ...)
38{ 38{
39 va_list args; 39 va_list args;
40 int i; 40 int i;
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
index ccf73258ebf7..b1ff9e87dcc6 100644
--- a/arch/sparc64/prom/tree.c
+++ b/arch/sparc64/prom/tree.c
@@ -69,7 +69,7 @@ prom_getsibling(int node)
69 * Return -1 on error. 69 * Return -1 on error.
70 */ 70 */
71__inline__ int 71__inline__ int
72prom_getproplen(int node, char *prop) 72prom_getproplen(int node, const char *prop)
73{ 73{
74 if((!node) || (!prop)) return -1; 74 if((!node) || (!prop)) return -1;
75 return p1275_cmd ("getproplen", 75 return p1275_cmd ("getproplen",
@@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop)
83 * was successful the length will be returned, else -1 is returned. 83 * was successful the length will be returned, else -1 is returned.
84 */ 84 */
85__inline__ int 85__inline__ int
86prom_getproperty(int node, char *prop, char *buffer, int bufsize) 86prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
87{ 87{
88 int plen; 88 int plen;
89 89
90 plen = prom_getproplen(node, prop); 90 plen = prom_getproplen(node, prop);
91 if((plen > bufsize) || (plen == 0) || (plen == -1)) 91 if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
92 return -1; 92 return -1;
93 else { 93 } else {
94 /* Ok, things seem all right. */ 94 /* Ok, things seem all right. */
95 return p1275_cmd ("getprop", 95 return p1275_cmd(prom_getprop_name,
96 P1275_ARG(1,P1275_ARG_IN_STRING)| 96 P1275_ARG(1,P1275_ARG_IN_STRING)|
97 P1275_ARG(2,P1275_ARG_OUT_BUF)| 97 P1275_ARG(2,P1275_ARG_OUT_BUF)|
98 P1275_INOUT(4, 1), 98 P1275_INOUT(4, 1),
99 node, prop, buffer, P1275_SIZE(plen)); 99 node, prop, buffer, P1275_SIZE(plen));
100 } 100 }
101} 101}
102 102
@@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize)
104 * on failure. 104 * on failure.
105 */ 105 */
106__inline__ int 106__inline__ int
107prom_getint(int node, char *prop) 107prom_getint(int node, const char *prop)
108{ 108{
109 int intprop; 109 int intprop;
110 110
@@ -119,7 +119,7 @@ prom_getint(int node, char *prop)
119 */ 119 */
120 120
121int 121int
122prom_getintdefault(int node, char *property, int deflt) 122prom_getintdefault(int node, const char *property, int deflt)
123{ 123{
124 int retval; 124 int retval;
125 125
@@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt)
131 131
132/* Acquire a boolean property, 1=TRUE 0=FALSE. */ 132/* Acquire a boolean property, 1=TRUE 0=FALSE. */
133int 133int
134prom_getbool(int node, char *prop) 134prom_getbool(int node, const char *prop)
135{ 135{
136 int retval; 136 int retval;
137 137
@@ -145,7 +145,7 @@ prom_getbool(int node, char *prop)
145 * buffer. 145 * buffer.
146 */ 146 */
147void 147void
148prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) 148prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
149{ 149{
150 int len; 150 int len;
151 151
@@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
160 * YES = 1 NO = 0 160 * YES = 1 NO = 0
161 */ 161 */
162int 162int
163prom_nodematch(int node, char *name) 163prom_nodematch(int node, const char *name)
164{ 164{
165 char namebuf[128]; 165 char namebuf[128];
166 prom_getproperty(node, "name", namebuf, sizeof(namebuf)); 166 prom_getproperty(node, "name", namebuf, sizeof(namebuf));
@@ -172,7 +172,7 @@ prom_nodematch(int node, char *name)
172 * 'nodename'. Return node if successful, zero if not. 172 * 'nodename'. Return node if successful, zero if not.
173 */ 173 */
174int 174int
175prom_searchsiblings(int node_start, char *nodename) 175prom_searchsiblings(int node_start, const char *nodename)
176{ 176{
177 177
178 int thisnode, error; 178 int thisnode, error;
@@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer)
294 * property types for this node. 294 * property types for this node.
295 */ 295 */
296__inline__ char * 296__inline__ char *
297prom_nextprop(int node, char *oprop, char *buffer) 297prom_nextprop(int node, const char *oprop, char *buffer)
298{ 298{
299 char buf[32]; 299 char buf[32];
300 300
@@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer)
314} 314}
315 315
316int 316int
317prom_finddevice(char *name) 317prom_finddevice(const char *name)
318{ 318{
319 if(!name) return 0; 319 if (!name)
320 return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)| 320 return 0;
321 P1275_INOUT(1, 1), 321 return p1275_cmd(prom_finddev_name,
322 name); 322 P1275_ARG(0,P1275_ARG_IN_STRING)|
323 P1275_INOUT(1, 1),
324 name);
323} 325}
324 326
325int prom_node_has_property(int node, char *prop) 327int prom_node_has_property(int node, const char *prop)
326{ 328{
327 char buf [32]; 329 char buf [32];
328 330
@@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop)
339 * of 'size' bytes. Return the number of bytes the prom accepted. 341 * of 'size' bytes. Return the number of bytes the prom accepted.
340 */ 342 */
341int 343int
342prom_setprop(int node, char *pname, char *value, int size) 344prom_setprop(int node, const char *pname, char *value, int size)
343{ 345{
344 if(size == 0) return 0; 346 if(size == 0) return 0;
345 if((pname == 0) || (value == 0)) return 0; 347 if((pname == 0) || (value == 0)) return 0;
@@ -364,7 +366,7 @@ prom_inst2pkg(int inst)
364 * FIXME: Should work for v0 as well 366 * FIXME: Should work for v0 as well
365 */ 367 */
366int 368int
367prom_pathtoinode(char *path) 369prom_pathtoinode(const char *path)
368{ 370{
369 int node, inst; 371 int node, inst;
370 372