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 static void runkernel(void)
168 {
169 __asm__ __volatile__(
170 "bis %1,%1,$30\n\t"
171 "bis %0,%0,$26\n\t"
172 "ret ($26)"
173 :
174 : "r" (START_ADDR),
175 "r" (PAGE_SIZE + INIT_STACK));
176 }
177
178 void start_kernel(void)
179 {
180 long i;
181 long dev;
182
183 printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
184 if (hwrpb.pagesize != 8192) {
185 printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
186 return;
187 }
188 pal_init();
189 dev = openboot();
190 if (dev < 0) {
191 printk("Unable to open boot device: %016lx\n", dev);
192 return;
193 }
194 dev &= 0xffffffff;
195 printk("Loading vmlinux ...");
196 i = load(dev, START_ADDR, START_SIZE);
197 close(dev);
198 if (i != START_SIZE) {
199 printk("Failed (%lx)\n", i);
200 return;
201 }
202 printk(" Ok\nNow booting the kernel\n");
203 runkernel();
204 for (i = 0 ; i < 0x100000000 ; i++)
205 ;
206 halt();
207 }