1 /* $NetBSD: boot.c,v 1.2 2007/12/17 19:54:32 garbled Exp $ */
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <lib/libsa/stand.h>
35 #include <lib/libsa/loadfile.h>
36 #include <lib/libkern/libkern.h>
37 #include <sys/reboot.h>
38 #include <sys/boot_flag.h>
39 #include <machine/bootinfo.h>
40 #include <machine/cpu.h>
41 #include <machine/iplcb.h>
42 #include <powerpc/spr.h>
49 #define NUMNAMES (sizeof (names) / sizeof (names[0]))
52 char namebuf
[NAMELEN
];
53 char nametmp
[NAMELEN
];
55 unsigned char cregs
[10];
57 char bootinfo
[BOOTINFO_MAXSIZE
];
58 struct btinfo_iplcb btinfo_iplcb
;
59 struct btinfo_console btinfo_console
;
61 /*struct ipl_cb iplcb;
62 struct ipl_directory ipldir;*/
64 extern u_long ns_per_tick
;
65 extern char bootprog_name
[], bootprog_rev
[], bootprog_maker
[], bootprog_date
[];
67 void boot(void *, void *);
68 static void exec_kernel(char *);
71 #define PSL_EE 0x00008000
72 #define BAT_BL_128K 0x00000000
73 #define BAT_BL_1M 0x0000001c
74 #define BAT_BL_2M 0x0000003c
75 #define BAT_W 0x00000040
76 #define BAT_I 0x00000020
77 #define BAT_M 0x00000010
78 #define BAT_G 0x00000008
79 #define BAT_X 0x00000004
80 #define BAT_Vs 0x00000002
81 #define BAT_Vu 0x00000001
82 #define BAT_PP_RW 0x00000002
83 #define BAT_RPN (~0x1ffff)
84 #define BAT_EPI (~0x1ffffL)
85 #define BAT_V (BAT_Vs|BAT_Vu)
86 #define BAT_BL 0x00001ffc
88 #define BATU(va, len, v) \
89 (((va) & BAT_EPI) | ((len) & BAT_BL) | ((v) & BAT_V))
90 #define BATL(pa, wimg, pp) \
91 (((pa) & BAT_RPN) | (wimg) | (pp))
98 register_t savemsr
, msr
, savesr15
;
100 __asm
volatile ("mfmsr %0" : "=r"(savemsr
));
101 msr
= savemsr
& ~PSL_DR
;
102 __asm
volatile ("mtmsr %0" : : "r"(msr
));
104 __asm
volatile ("mfsr %0,15;isync" : "=r"(savesr15
));
105 __asm
volatile ("mtsr 15,%0" : : "r"(0x82040080));
106 __asm
volatile ("mtmsr %0" : : "r"(msr
|PSL_DR
));
107 __asm
volatile ("isync");
108 *(uint32_t *)0xF0A00300 = val
;
109 __asm
volatile ("mtmsr %0" : : "r"(savemsr
));
110 __asm
volatile ("mtsr 15,%0;isync" : : "r"(savesr15
));
113 register_t savemsr
, msr
, batu
, batl
;
116 __asm
volatile ("mfmsr %0" : "=r"(savemsr
));
117 msr
= savemsr
|PSL_DR
;
118 __asm
volatile ("mtmsr %0" : : "r"(msr
));
119 __asm
volatile ("isync");
121 /* set up a bat and map the whole NVRAM chunk */
122 batl
= BATL(0xFF600000, BAT_I
|BAT_G
, BAT_PP_RW
);
123 batu
= BATU(0xFF600000, BAT_BL_1M
, BAT_Vs
);
124 __asm
volatile ("mtdbatl 1,%0; mtdbatu 1,%1;"
125 :: "r"(batl
), "r"(batu
));
126 __asm
volatile ("isync");
128 *(volatile uint32_t *)0xFF600300 = val
;
129 __asm
volatile ("eieio");
130 __asm
volatile ("isync");
132 /* put back to normal */
133 __asm
volatile ("mtmsr %0" : : "r"(savemsr
));
134 __asm
volatile ("isync");
142 boot(void *iplcb_p
, void *extiplcb_p
)
144 extern char _end
[], _edata
[];
147 /*unsigned int cpuvers;*/
148 char *name
, *cnname
, *p
;
149 struct ipl_cb
*iplcb_ptr
;
150 struct ipl_directory
*dirp
;
151 struct ipl_info
*infop
;
153 //setled(0x30100000); /* we have control */
155 iplcb_ptr
= (struct ipl_cb
*)iplcb_p
;
156 dirp
= &(iplcb_ptr
->dir
);
158 /* Clear all of BSS */
159 memset(_edata
, 0, _end
- _edata
);
164 //setled(0x30000000); /* attempting r14 setup */
166 //setled(0x31000000); /* attempting console init */
167 cnname
= cninit(&addr
, &speed
);
169 //setled(0x31100000); /* we have the console */
171 printf("IPLCB ptr = 0x%p\n", iplcb_p
);
173 infop
= (struct ipl_info
*)((char *)iplcb_p
+ dirp
->iplinfo_off
);
174 printf("Machine model = 0x%x\n", infop
->model
);
175 printf("RAM = 0x%x\n", infop
->ram_size
);
177 //dump_iplcb(iplcb_p);
183 btinfo_iplcb
.common
.next
= sizeof(btinfo_iplcb
);
184 btinfo_iplcb
.common
.type
= BTINFO_IPLCB
;
186 btinfo_iplcb
.addr
= (void *)iplcb_p
;
188 printf("Warning: no IPL Control Block.\n");
189 btinfo_iplcb
.addr
= 0;
195 btinfo_console
.common
.next
= sizeof(btinfo_console
);
196 btinfo_console
.common
.type
= BTINFO_CONSOLE
;
197 strcpy(btinfo_console
.devname
, cnname
);
198 btinfo_console
.addr
= addr
;
199 btinfo_console
.speed
= speed
;
202 memcpy(p
, (void *)&btinfo_iplcb
, sizeof(btinfo_iplcb
));
203 p
+= sizeof(btinfo_iplcb
);
204 memcpy(p
, (void *)&btinfo_console
, sizeof(btinfo_console
));
205 p
+= sizeof(btinfo_console
);
208 * load kernel if attached
212 setled(0x38000000); /* attempting boot */
214 printf(">> %s, Revision %s\n", bootprog_name
, bootprog_rev
);
215 printf(">> (%s, %s)\n", bootprog_maker
, bootprog_date
);
221 setled(0x38100000 + (0x100000 * n
));
223 setled(0x39900000); /* boot failed! */
231 exec_kernel(char *name
)
235 u_long marks
[MARK_MAX
];
238 extern int db_monitor(void);
241 #endif /* DBMONITOR */
243 memset(namebuf
, 0, sizeof (namebuf
));
244 if (tgets(namebuf
) == -1)
251 if (*(++ptr
) == NULL
) {
259 #endif /* DBMONITOR */
266 while ((c
= *++ptr
) && c
!= ' ')
270 while ((c
= *++ptr
) && c
!= ' ');
277 printf("Loading %s", name
);
279 printf(" (howto 0x%x)", howto
);
282 marks
[MARK_START
] = 0;
283 if (loadfile(name
, marks
, LOAD_ALL
) == 0) {
289 #endif /* DBMONITOR */
291 printf("start=0x%lx\n\n", marks
[MARK_ENTRY
]);
293 __syncicache((void *)marks
[MARK_ENTRY
],
294 (u_int
)marks
[MARK_SYM
] - (u_int
)marks
[MARK_ENTRY
]);
295 printf("About to run\n");
296 run((void *)marks
[MARK_SYM
],
297 (void *)marks
[MARK_END
],
300 (void *)marks
[MARK_ENTRY
]);