3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
7 * Copyright (C) 1999 by Helge Deller
8 * Copyright 1999 SuSE GmbH (Philipp Rumpf)
9 * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
11 * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
14 #include <linux/autoconf.h> /* for CONFIG_SMP */
16 #include <asm/offsets.h>
19 #include <asm/assembly.h>
20 #include <asm/pgtable.h>
36 .import init_thread_union,data
37 .import $global$ /* forward declaration */
38 .import fault_vector_11,code /* IVA parisc 1.1 32 bit */
39 .import fault_vector_20,code /* IVA parisc 2.0 32 bit */
42 .export _stext,data /* Kernel want it this way! */
48 /* Make sure sr4-sr7 are set to zero for the kernel address space */
54 /* Clear BSS (shouldn't the boot loader do this?) */
56 .import __bss_start,data
57 .import __bss_stop,data
59 ldil L%PA(__bss_start),%r3
60 ldo R%PA(__bss_start)(%r3),%r3
61 ldil L%PA(__bss_stop),%r4
62 ldo R%PA(__bss_stop)(%r4),%r4
64 cmpb,<<,n %r3,%r4,$bss_loop
67 /* Save away the arguments the boot loader passed in (32 bit args) */
69 ldil L%PA(boot_args),%r1
70 ldo R%PA(boot_args)(%r1),%r1
76 /* Initialize startup VM. Just map first 8 MB of memory */
78 ldo R%PA(pg0)(%r1),%r1
79 ldo _PAGE_TABLE(%r1),%r3
81 ldil L%PA(swapper_pg_dir),%r4
82 ldo R%PA(swapper_pg_dir)(%r4),%r4
83 mtctl %r4,%cr24 /* Initialize kernel root pointer */
84 mtctl %r4,%cr25 /* Initialize user root pointer */
85 ldi ASM_PT_INITIAL,%r1
86 ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
89 ldo ASM_PAGE_SIZE(%r3),%r3
91 ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
93 ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
95 ldo R%PA(pg0)(%r1),%r1
97 stwm %r3,ASM_PTE_ENTRY_SIZE(%r1)
98 ldo ASM_PAGE_SIZE(%r3),%r3
99 bb,>= %r3,31-KERNEL_INITIAL_ORDER,$pgt_fill_loop
103 /* Load the return address...er...crash 'n burn */
106 /* And the RFI Target address too */
107 ldil L%start_kernel,%r11
108 ldo R%start_kernel(%r11),%r11
110 /* And the initial task pointer */
112 ldil L%init_thread_union,%r6
113 ldo R%init_thread_union(%r6),%r6
116 /* And the stack pointer too */
118 ldo THREAD_SZ_ALGN(%r6),%sp
120 /* And the interrupt stack */
122 ldil L%interrupt_stack,%r6
123 ldo R%interrupt_stack(%r6),%r6
127 /* Set the smp rendevous address into page zero.
128 ** It would be safer to do this in init_smp_config() but
129 ** it's just way easier to deal with here because
130 ** of 64-bit function ptrs and the address is local to this file.
132 ldil L%PA(smp_slave_stext),%r10
133 ldo R%PA(smp_slave_stext)(%r10),%r10
134 stw %r10,0x10(%r0) /* MEM_RENDEZ */
135 stw %r0,0x28(%r0) /* MEM_RENDEZ_HI - assume addr < 4GB */
141 ** Code Common to both Monarch and Slave processors.
143 ** %r11 must contain RFI target address.
144 ** %r25/%r26 args to pass to target function
145 ** %r2 in case rfi target decides it didn't like something
147 ** Caller must init: SR4-7, %sp, %r10, %cr24/25,
153 /* Clear PDC entry point - we won't use it */
154 stw %r0,0x10(%r0) /* MEM_RENDEZ */
155 stw %r0,0x28(%r0) /* MEM_RENDEZ_HI */
158 /* PARANOID: clear user scratch/user space SR's */
164 /* Initialize Protection Registers */
170 /* Initialize the global data pointer */
172 ldo R%$global$(%dp),%dp
175 * Set up our interrupt table. HPMCs might not work after this!
177 * We need to install the correct iva for PA1.1 or PA2.0. The
178 * following short sequence of instructions can determine this
179 * (without being illegal on a PA1.1 machine).
186 comib,<>,n 0,%r10,$is_pa20
187 ldil L%PA(fault_vector_11),%r10
189 ldo R%PA(fault_vector_11)(%r10),%r10
192 ldil L%PA(fault_vector_20),%r10
193 ldo R%PA(fault_vector_20)(%r10),%r10
198 /* Disable Q bit so we can load the iia queue */
202 * - no interruptions except HPMC and TOC (which are handled by PDC)
203 * - Q bit set (IODC / PDC interruptions)
207 ldil L%KERNEL_PSW,%r10
208 ldo R%KERNEL_PSW(%r10),%r10
211 /* Set the space pointers for the post-RFI world
212 ** Clear the two-level IIA Space Queue, effectively setting
215 mtctl %r0,%cr17 /* Clear IIASQ tail */
216 mtctl %r0,%cr17 /* Clear IIASQ head */
218 /* Load RFI target into PC queue */
219 mtctl %r11,%cr18 /* IIAOQ head */
221 mtctl %r11,%cr18 /* IIAOQ tail */
223 /* Jump to hyperspace */
231 .import smp_init_current_idle_task,data
232 .import smp_callin,code
237 break 1,1 /* Break if returned from start_secondary */
242 /***************************************************************************
244 * smp_slave_stext is executed by all non-monarch Processors when the Monarch
245 * pokes the slave CPUs in smp.c:smp_boot_cpus().
247 * Once here, registers values are initialized in order to branch to virtual
248 * mode. Once all available/eligible CPUs are in virtual mode, all are
249 * released and start out by executing their own idle task.
250 *****************************************************************************/
258 ** Initialize Space registers
265 /* Initialize the SP - monarch sets up smp_init_current_idle_task */
266 ldil L%PA(smp_init_current_idle_task),%sp
267 ldo R%PA(smp_init_current_idle_task)(%sp),%sp
268 ldw 0(%sp),%sp /* load task address */
269 mtctl %sp,%cr30 /* store in cr30 */
270 addil L%THREAD_SZ_ALGN,%sp /* stack is above task */
271 ldo R%THREAD_SZ_ALGN(%r1),%sp
273 /* point CPU to kernel page tables */
274 ldil L%PA(swapper_pg_dir),%r4
275 ldo R%PA(swapper_pg_dir)(%r4),%r4
276 mtctl %r4,%cr24 /* Initialize kernel root pointer */
277 mtctl %r4,%cr25 /* Initialize user root pointer */
279 /* Load RFI *return* address in case smp_callin bails */
280 ldil L%smp_callin_rtn,%r2
281 ldo R%smp_callin_rtn(%r2),%r2
283 /* Load RFI target address. */
284 ldil L%smp_callin,%r11
285 ldo R%smp_callin(%r11),%r11
287 /* ok...common code can handle the rest */
292 #endif /* CONFIG_SMP */
297 .export $global$,data
299 .type $global$,@object