8 #define PAGE_SIZE (1ul << PAGE_SHIFT)
9 #define PAGE_OFFSET 0xfffffc0000000000UL
11 #define VPTPTR 0xfffffffe00000000UL
13 #define PA(VA) ((unsigned long)(VA) & 0xfffffffffful)
14 #define VA(PA) ((void *)(PA) + PAGE_OFFSET)
18 struct hwrpb_combine
{
19 struct hwrpb_struct hwrpb
;
20 struct percpu_struct processor
;
21 struct memdesc_struct md
;
22 struct memclust_struct mc
[2];
25 extern char stack
[PAGE_SIZE
] __attribute__((section(".sbss")));
26 extern char _end
[] __attribute__((visibility("hidden"), nocommon
));
28 struct pcb_struct pcb
__attribute__((section(".sbss")));
30 static unsigned long page_dir
[1024] __attribute__((aligned(PAGE_SIZE
)));
32 /* The HWRPB must be aligned because it is exported at INIT_HWRPB. */
33 struct hwrpb_combine hwrpb
__attribute__((aligned(PAGE_SIZE
)));
35 static void *last_alloc
;
38 alloc (unsigned long size
, unsigned long align
)
40 void *p
= (void *)(((unsigned long)last_alloc
+ align
- 1) & ~(align
- 1));
41 last_alloc
= p
+ size
;
42 return memset (p
, 0, size
);
45 static inline unsigned long
46 pt_index(unsigned long addr
, int level
)
48 return (addr
>> (PAGE_SHIFT
+ (10 * level
))) & 0x3ff;
51 static inline unsigned long
52 build_pte (void *page
)
56 bits
= PA((unsigned long)page
) << (32 - PAGE_SHIFT
);
57 bits
+= _PAGE_VALID
| _PAGE_KRE
| _PAGE_KWE
;
63 pte_page (unsigned long pte
)
65 return VA(pte
>> 32 << PAGE_SHIFT
);
69 set_pte (unsigned long addr
, void *page
)
71 unsigned long *pt
= page_dir
;
74 index
= pt_index(addr
, 2);
76 pt
= pte_page (pt
[index
]);
79 unsigned long *npt
= alloc(PAGE_SIZE
, PAGE_SIZE
);
80 pt
[index
] = build_pte (npt
);
84 index
= pt_index(addr
, 1);
86 pt
= pte_page (pt
[index
]);
89 unsigned long *npt
= alloc(PAGE_SIZE
, PAGE_SIZE
);
90 pt
[index
] = build_pte (npt
);
94 index
= pt_index(addr
, 0);
95 pt
[index
] = build_pte (page
);
101 /* Install the self-reference for the virtual page table base register. */
102 page_dir
[pt_index(VPTPTR
, 2)] = build_pte(page_dir
);
104 set_pte ((unsigned long)INIT_HWRPB
, &hwrpb
);
106 /* ??? SRM maps some amount of memory at 0x20000000 for use by programs
107 started from the console prompt. Including the bootloader. While
108 we're emulating MILO, don't bother as we jump straight to the kernel
112 static inline unsigned long
115 unsigned long implver
, amask
;
117 implver
= __builtin_alpha_implver();
118 amask
= ~__builtin_alpha_amask(-1);
126 if ((amask
& 0x101) == 0x101) /* MAX + BWX */
128 if (amask
& 1) /* BWX */
133 if (amask
& 4) /* CIX */
141 init_hwrpb (unsigned long memsize
)
143 unsigned long pal_pages
;
145 hwrpb
.hwrpb
.phys_addr
= PA(&hwrpb
);
147 /* Yes, the 'HWRPB' magic is in big-endian byte ordering. */
148 hwrpb
.hwrpb
.id
= ( (long)'H' << 56
154 hwrpb
.hwrpb
.size
= sizeof(struct hwrpb_struct
);
156 /* The inclusion of MILO here tells the Linux kernel that we do
157 not (yet) support any of the extended console support routines
159 ((int *)hwrpb
.hwrpb
.ssn
)[0] = ( 'M' << 0
163 ((int *)hwrpb
.hwrpb
.ssn
)[1] = ( ' ' << 0
167 ((int *)hwrpb
.hwrpb
.ssn
)[2] = ( 'U' << 0);
169 /* For now, hard-code emulation of sx164. */
170 hwrpb
.hwrpb
.cpuid
= PCA56_CPU
;
171 hwrpb
.hwrpb
.pagesize
= PAGE_SIZE
;
172 hwrpb
.hwrpb
.pa_bits
= 40;
173 hwrpb
.hwrpb
.max_asn
= 127;
174 hwrpb
.hwrpb
.sys_type
= ST_DEC_EB164
;
175 hwrpb
.hwrpb
.sys_variation
= 15 << 10;
176 hwrpb
.hwrpb
.sys_revision
= 0;
177 hwrpb
.processor
.type
= PCA56_CPU
;
179 hwrpb
.hwrpb
.intr_freq
= HZ
* 4096;
181 /* ??? What the hell should we put here. Measure like the kernel will? */
182 hwrpb
.hwrpb
.cycle_freq
= 400000000;
184 hwrpb
.hwrpb
.vptb
= VPTPTR
;
186 hwrpb
.hwrpb
.nr_processors
= 1;
187 hwrpb
.hwrpb
.processor_size
= sizeof(struct percpu_struct
);
188 hwrpb
.hwrpb
.processor_offset
= offsetof(struct hwrpb_combine
, processor
);
190 hwrpb
.hwrpb
.mddt_offset
= offsetof(struct hwrpb_combine
, md
);
191 hwrpb
.md
.numclusters
= 2;
193 pal_pages
= (PA(last_alloc
) + PAGE_SIZE
- 1) >> PAGE_SHIFT
;
195 hwrpb
.mc
[0].numpages
= pal_pages
;
196 hwrpb
.mc
[0].usage
= 1;
197 hwrpb
.mc
[1].start_pfn
= pal_pages
;
198 hwrpb
.mc
[1].numpages
= (memsize
>> PAGE_SHIFT
) - pal_pages
;
201 unsigned long sum
= 0, *l
;
202 for (l
= (unsigned long *) &hwrpb
.hwrpb
; l
< &hwrpb
.hwrpb
.chksum
; ++l
)
204 hwrpb
.hwrpb
.chksum
= sum
;
211 pcb
.ksp
= (unsigned long)stack
+ sizeof(stack
);
212 pcb
.ptbr
= PA(page_dir
) >> PAGE_SHIFT
;
213 pcb
.flags
= 1; /* FEN */
219 uart_puts(COM1
, "Hello, World!\n");
221 __builtin_unreachable ();
225 do_start(unsigned long memsize
, void (*kernel_entry
)(void))
235 register int variant
__asm__("$16") = 2; /* OSF/1 PALcode */
236 register void (*pc
)(void) __asm__("$17");
237 register unsigned long pa_pcb
__asm__("$18");
238 register unsigned long vptptr
__asm__("$19");
240 pc
= (kernel_entry
? kernel_entry
: do_hello
);
243 asm("call_pal 0x0a" : : "r"(variant
), "r"(pc
), "r"(pa_pcb
), "r"(vptptr
));
245 __builtin_unreachable ();