This source file includes following definitions.
- printk
- find_pa
- pal_init
- openboot
- close
- load
- runkernel
- start_kernel
1
2
3
4
5
6
7
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 #include <linux/version.h>
11 #include <linux/mm.h>
12
13 #include <asm/system.h>
14 #include <asm/console.h>
15 #include <asm/hwrpb.h>
16
17 #include <stdarg.h>
18
19 extern int vsprintf(char *, const char *, va_list);
20 extern unsigned long switch_to_osf_pal(unsigned long nr,
21 struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
22 unsigned long vptb, unsigned long *kstk);
23
24 int printk(const char * fmt, ...)
25 {
26 va_list args;
27 int i, j, written, remaining, num_nl;
28 static char buf[1024];
29 char * str;
30
31 va_start(args, fmt);
32 i = vsprintf(buf, fmt, args);
33 va_end(args);
34
35
36
37 num_nl = 0;
38 for (j = 0; j < i; ++j) {
39 if (buf[j] == '\n')
40 ++num_nl;
41 }
42 remaining = i + num_nl;
43 for (j = i - 1; j >= 0; --j) {
44 buf[j + num_nl] = buf[j];
45 if (buf[j] == '\n') {
46 --num_nl;
47 buf[j + num_nl] = '\r';
48 }
49 }
50
51 str = buf;
52 do {
53 written = puts(str, remaining);
54 remaining -= written;
55 str += written;
56 } while (remaining > 0);
57 return i;
58 }
59
60 #define hwrpb (*INIT_HWRPB)
61
62
63
64
65
66
67 struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
68 {
69 unsigned long address = (unsigned long) pcb;
70 unsigned long result;
71
72 result = vptb[address >> 13];
73 result >>= 32;
74 result <<= 13;
75 result |= address & 0x1fff;
76 return (struct pcb_struct *) result;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 #define pcb_va ((struct pcb_struct *) 0x20000000)
97 #define old_vptb (0x0000000200000000UL)
98 #define new_vptb (0xfffffffe00000000UL)
99 void pal_init(void)
100 {
101 unsigned long i, rev, sum;
102 unsigned long *L1, *l;
103 struct percpu_struct * percpu;
104 struct pcb_struct * pcb_pa;
105
106
107 L1 = (unsigned long *) 0x200802000UL;
108 L1[1023] = L1[1];
109
110 percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
111
112 pcb_va->ksp = 0;
113 pcb_va->usp = 0;
114 pcb_va->ptbr = L1[1] >> 32;
115 pcb_va->asn = 0;
116 pcb_va->pcc = 0;
117 pcb_va->unique = 0;
118 pcb_va->flags = 1;
119 pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
120 printk("Switching to OSF PAL-code .. ");
121
122
123
124
125
126
127
128 i = switch_to_osf_pal(
129 2,
130 pcb_va,
131 pcb_pa,
132 new_vptb,
133 0);
134 if (i) {
135 printk("failed, code %ld\n", i);
136 halt();
137 }
138 rev = percpu->pal_revision = percpu->palcode_avail[2];
139
140 hwrpb.vptb = new_vptb;
141
142
143 sum = 0;
144 for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l)
145 sum += *l;
146 hwrpb.chksum = sum;
147
148 printk("Ok (rev %lx)\n", rev);
149
150 L1[1] = 0;
151 invalidate_all();
152 }
153
154 extern int _end;
155
156 static inline long openboot(void)
157 {
158 char bootdev[256];
159 long result;
160
161 result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
162 if (result < 0)
163 return result;
164 return dispatch(CCB_OPEN, bootdev, result & 255);
165 }
166
167 static inline long close(long dev)
168 {
169 return dispatch(CCB_CLOSE, dev);
170 }
171
172 static inline long load(long dev, unsigned long addr, unsigned long count)
173 {
174 char bootfile[256];
175 long result;
176
177 result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
178 if (result < 0)
179 return result;
180 result &= 255;
181 bootfile[result] = '\0';
182 if (result)
183 printk("Boot file specification (%s) not implemented\n", bootfile);
184 return dispatch(CCB_READ, dev, count, addr, BOOT_SIZE/512 + 1);
185 }
186
187
188
189
190 static void runkernel(void)
191 {
192 __asm__ __volatile__(
193 "bis %1,%1,$30\n\t"
194 "bis %0,%0,$26\n\t"
195 "ret ($26)"
196 :
197 : "r" (START_ADDR),
198 "r" (PAGE_SIZE + INIT_STACK));
199 }
200
201 void start_kernel(void)
202 {
203 long i;
204 long dev;
205 int nbytes;
206 char envval[256];
207
208 printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
209 if (hwrpb.pagesize != 8192) {
210 printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
211 return;
212 }
213 pal_init();
214 dev = openboot();
215 if (dev < 0) {
216 printk("Unable to open boot device: %016lx\n", dev);
217 return;
218 }
219 dev &= 0xffffffff;
220 printk("Loading vmlinux ...");
221 i = load(dev, START_ADDR, START_SIZE);
222 close(dev);
223 if (i != START_SIZE) {
224 printk("Failed (%lx)\n", i);
225 return;
226 }
227
228 nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
229 envval, sizeof(envval));
230 if (nbytes > 0) {
231 envval[nbytes] = '\0';
232 strcpy((char*)ZERO_PGE, envval);
233 }
234
235 printk(" Ok\nNow booting the kernel\n");
236 runkernel();
237 for (i = 0 ; i < 0x100000000 ; i++)
238 ;
239 halt();
240 }