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
12 #include <asm/system.h>
13 #include <asm/console.h>
14 #include <asm/hwrpb.h>
15 #include <asm/page.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;
79 unsigned long *L1;
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 hwrpb.vptb = new_vptb;
117 printk("Ok (rev %lx)\n", rev);
118
119 L1[1] = 0;
120 invalidate_all();
121 }
122
123 extern int _end;
124
125 static inline long openboot(void)
126 {
127 char bootdev[256];
128 long result;
129
130 result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
131 if (result < 0)
132 return result;
133 return dispatch(CCB_OPEN, bootdev, result & 255);
134 }
135
136 static inline long close(long dev)
137 {
138 return dispatch(CCB_CLOSE, dev);
139 }
140
141 static inline long load(long dev, unsigned long addr, unsigned long count)
142 {
143 char bootfile[256];
144 long result;
145
146 result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
147 if (result < 0)
148 return result;
149 result &= 255;
150 bootfile[result] = '\0';
151 if (result)
152 printk("Boot file specification (%s) not implemented\n", bootfile);
153 return dispatch(CCB_READ, dev, count, addr, BOOT_SIZE/512 + 1);
154 }
155
156 static void runkernel(void)
157 {
158 struct pcb_struct * init_pcb = (struct pcb_struct *) INIT_PCB;
159
160 *init_pcb = *pcb_va;
161 init_pcb->ksp = PAGE_SIZE + INIT_STACK;
162
163 __asm__ __volatile__(
164 "bis %0,%0,$26\n\t"
165 "bis %1,%1,$16\n\t"
166 ".long %2\n\t"
167 "ret ($26)"
168 :
169 : "r" (START_ADDR),
170 "r" (init_pcb),
171 "i" (PAL_swpctx)
172 : "$16","$26");
173 }
174
175 void start_kernel(void)
176 {
177 long i;
178 long dev;
179
180 printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
181 if (hwrpb.pagesize != 8192) {
182 printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
183 return;
184 }
185 pal_init();
186 dev = openboot();
187 if (dev < 0) {
188 printk("Unable to open boot device: %016lx\n", dev);
189 return;
190 }
191 dev &= 0xffffffff;
192 printk("Loading vmlinux ...");
193 i = load(dev, START_ADDR, START_SIZE);
194 close(dev);
195 if (i != START_SIZE) {
196 printk("Failed (%lx)\n", i);
197 return;
198 }
199 printk(" Ok\nNow booting the kernel\n");
200 runkernel();
201 for (i = 0 ; i < 0x100000000 ; i++)
202 ;
203 halt();
204 }