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;
28 static char buf[1024];
29
30 va_start(args, fmt);
31 i = vsprintf(buf, fmt, args);
32 va_end(args);
33 puts(buf,i);
34 return i;
35 }
36
37 #define hwrpb (*INIT_HWRPB)
38
39
40
41
42
43
44 struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
45 {
46 unsigned long address = (unsigned long) pcb;
47 unsigned long result;
48
49 result = vptb[address >> 13];
50 result >>= 32;
51 result <<= 13;
52 result |= address & 0x1fff;
53 return (struct pcb_struct *) result;
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 #define pcb_va ((struct pcb_struct *) 0x20000000)
74 #define old_vptb (0x0000000200000000UL)
75 #define new_vptb (0xfffffffe00000000UL)
76 void pal_init(void)
77 {
78 unsigned long i, rev, sum;
79 unsigned long *L1, *l;
80 struct percpu_struct * percpu;
81 struct pcb_struct * pcb_pa;
82
83
84 L1 = (unsigned long *) 0x200802000UL;
85 L1[1023] = L1[1];
86
87 percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
88
89 pcb_va->ksp = 0;
90 pcb_va->usp = 0;
91 pcb_va->ptbr = L1[1] >> 32;
92 pcb_va->asn = 0;
93 pcb_va->pcc = 0;
94 pcb_va->unique = 0;
95 pcb_va->flags = 1;
96 pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
97 printk("Switching to OSF PAL-code .. ");
98
99
100
101
102
103
104
105 i = switch_to_osf_pal(
106 2,
107 pcb_va,
108 pcb_pa,
109 new_vptb,
110 0);
111 if (i) {
112 printk("failed, code %ld\n", i);
113 halt();
114 }
115 rev = percpu->pal_revision = percpu->palcode_avail[2];
116
117 hwrpb.vptb = new_vptb;
118
119
120 sum = 0;
121 for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l)
122 sum += *l;
123 hwrpb.chksum = sum;
124
125 printk("Ok (rev %lx)\n", rev);
126
127 L1[1] = 0;
128 invalidate_all();
129 }
130
131 extern int _end;
132
133 static inline long openboot(void)
134 {
135 char bootdev[256];
136 long result;
137
138 result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
139 if (result < 0)
140 return result;
141 return dispatch(CCB_OPEN, bootdev, result & 255);
142 }
143
144 static inline long close(long dev)
145 {
146 return dispatch(CCB_CLOSE, dev);
147 }
148
149 static inline long load(long dev, unsigned long addr, unsigned long count)
150 {
151 char bootfile[256];
152 long result;
153
154 result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
155 if (result < 0)
156 return result;
157 result &= 255;
158 bootfile[result] = '\0';
159 if (result)
160 printk("Boot file specification (%s) not implemented\n", bootfile);
161 return dispatch(CCB_READ, dev, count, addr, BOOT_SIZE/512 + 1);
162 }
163
164
165
166
167
168
169
170 static void runkernel(void)
171 {
172 struct pcb_struct * init_pcb = (struct pcb_struct *) INIT_PCB;
173 unsigned long oldptbr, *oldL1;
174 unsigned long newptbr, *newL1;
175
176 oldptbr = pcb_va->ptbr;
177 oldL1 = (unsigned long *) (PAGE_OFFSET + (oldptbr << PAGE_SHIFT));
178
179 newptbr = (SWAPPER_PGD - PAGE_OFFSET) >> PAGE_SHIFT;
180 newL1 = (unsigned long *) SWAPPER_PGD;
181
182 memcpy(newL1, oldL1, PAGE_SIZE);
183 newL1[1023] = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
184
185 *init_pcb = *pcb_va;
186 init_pcb->ksp = PAGE_SIZE + INIT_STACK;
187 init_pcb->ptbr = newptbr;
188
189 __asm__ __volatile__(
190 "bis %0,%0,$26\n\t"
191 "bis %1,%1,$16\n\t"
192 ".long %2\n\t"
193 "lda $16,-2($31)\n\t"
194 ".long 51\n\t"
195 "ret ($26)"
196 :
197 : "r" (START_ADDR),
198 "r" (init_pcb),
199 "i" (PAL_swpctx)
200 : "$16","$26");
201 }
202
203 void start_kernel(void)
204 {
205 long i;
206 long dev;
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 printk(" Ok\nNow booting the kernel\n");
228 runkernel();
229 for (i = 0 ; i < 0x100000000 ; i++)
230 ;
231 halt();
232 }