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