/* This file is subject to the terms and conditions of the GNU General Public1* License. See the file "COPYING" in the main directory of this archive2* for more details.3*4* Copyright (C) 1999-2007 by Helge Deller <[email protected]>5* Copyright 1999 SuSE GmbH (Philipp Rumpf)6* Copyright 1999 Philipp Rumpf ([email protected])7* Copyright 2000 Hewlett Packard (Paul Bame, [email protected])8* Copyright (C) 2001 Grant Grundler (Hewlett Packard)9* Copyright (C) 2004 Kyle McMartin <[email protected]>10*11* Initial Version 04-23-1999 by Helge Deller <[email protected]>12*/1314#include <asm/asm-offsets.h>15#include <asm/psw.h>16#include <asm/pdc.h>1718#include <asm/assembly.h>19#include <asm/pgtable.h>2021#include <linux/linkage.h>22#include <linux/init.h>2324.level LEVEL2526__INITDATA27ENTRY(boot_args)28.word 0 /* arg0 */29.word 0 /* arg1 */30.word 0 /* arg2 */31.word 0 /* arg3 */32END(boot_args)3334__HEAD3536.align 437.import init_thread_union,data38.import fault_vector_20,code /* IVA parisc 2.0 32 bit */39#ifndef CONFIG_64BIT40.import fault_vector_11,code /* IVA parisc 1.1 32 bit */41.import $global$ /* forward declaration */42#endif /*!CONFIG_64BIT*/43.export _stext,data /* Kernel want it this way! */44_stext:45ENTRY(stext)46.proc47.callinfo4849/* Make sure sr4-sr7 are set to zero for the kernel address space */50mtsp %r0,%sr451mtsp %r0,%sr552mtsp %r0,%sr653mtsp %r0,%sr75455/* Clear BSS (shouldn't the boot loader do this?) */5657.import __bss_start,data58.import __bss_stop,data5960load32 PA(__bss_start),%r361load32 PA(__bss_stop),%r462$bss_loop:63cmpb,<<,n %r3,%r4,$bss_loop64stw,ma %r0,4(%r3)6566/* Save away the arguments the boot loader passed in (32 bit args) */67load32 PA(boot_args),%r168stw,ma %arg0,4(%r1)69stw,ma %arg1,4(%r1)70stw,ma %arg2,4(%r1)71stw,ma %arg3,4(%r1)7273/* Initialize startup VM. Just map first 8/16 MB of memory */74load32 PA(swapper_pg_dir),%r475mtctl %r4,%cr24 /* Initialize kernel root pointer */76mtctl %r4,%cr25 /* Initialize user root pointer */7778#if PT_NLEVELS == 379/* Set pmd in pgd */80load32 PA(pmd0),%r581shrd %r5,PxD_VALUE_SHIFT,%r382ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r383stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)84ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r485#else86/* 2-level page table, so pmd == pgd */87ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r488#endif8990/* Fill in pmd with enough pte directories */91load32 PA(pg0),%r192SHRREG %r1,PxD_VALUE_SHIFT,%r393ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r39495ldi ASM_PT_INITIAL,%r196971:98stw %r3,0(%r4)99ldo (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3100addib,> -1,%r1,1b101#if PT_NLEVELS == 3102ldo ASM_PMD_ENTRY_SIZE(%r4),%r4103#else104ldo ASM_PGD_ENTRY_SIZE(%r4),%r4105#endif106107108/* Now initialize the PTEs themselves. We use RWX for109* everything ... it will get remapped correctly later */110ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */111ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */112load32 PA(pg0),%r1113114$pgt_fill_loop:115STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)116ldo (1<<PFN_PTE_SHIFT)(%r3),%r3 /* add one PFN */117addib,> -1,%r11,$pgt_fill_loop118nop119120/* Load the return address...er...crash 'n burn */121copy %r0,%r2122123/* And the RFI Target address too */124load32 start_parisc,%r11125126/* And the initial task pointer */127load32 init_thread_union,%r6128mtctl %r6,%cr30129130/* And the stack pointer too */131ldo THREAD_SZ_ALGN(%r6),%sp132133#ifdef CONFIG_SMP134/* Set the smp rendezvous address into page zero.135** It would be safer to do this in init_smp_config() but136** it's just way easier to deal with here because137** of 64-bit function ptrs and the address is local to this file.138*/139load32 PA(smp_slave_stext),%r10140stw %r10,0x10(%r0) /* MEM_RENDEZ */141stw %r0,0x28(%r0) /* MEM_RENDEZ_HI - assume addr < 4GB */142143/* FALLTHROUGH */144.procend145146/*147** Code Common to both Monarch and Slave processors.148** Entry:149**150** 1.1:151** %r11 must contain RFI target address.152** %r25/%r26 args to pass to target function153** %r2 in case rfi target decides it didn't like something154**155** 2.0w:156** %r3 PDCE_PROC address157** %r11 RFI target address158**159** Caller must init: SR4-7, %sp, %r10, %cr24/25,160*/161common_stext:162.proc163.callinfo164#else165/* Clear PDC entry point - we won't use it */166stw %r0,0x10(%r0) /* MEM_RENDEZ */167stw %r0,0x28(%r0) /* MEM_RENDEZ_HI */168#endif /*CONFIG_SMP*/169170#ifdef CONFIG_64BIT171tophys_r1 %sp172173/* Save the rfi target address */174ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10175tophys_r1 %r10176std %r11, TASK_PT_GR11(%r10)177/* Switch to wide mode Superdome doesn't support narrow PDC178** calls.179*/1801: mfia %rp /* clear upper part of pcoq */181ldo 2f-1b(%rp),%rp182depdi 0,31,32,%rp183bv (%rp)184ssm PSW_SM_W,%r0185186/* Set Wide mode as the "Default" (eg for traps)187** First trap occurs *right* after (or part of) rfi for slave CPUs.188** Someday, palo might not do this for the Monarch either.189*/1902:191#define MEM_PDC_LO 0x388192#define MEM_PDC_HI 0x35C193ldw MEM_PDC_LO(%r0),%r3194ldw MEM_PDC_HI(%r0),%r6195depd %r6, 31, 32, %r3 /* move to upper word */196197ldo PDC_PSW(%r0),%arg0 /* 21 */198ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */199ldo PDC_PSW_WIDE_BIT(%r0),%arg2 /* 2 */200load32 PA(stext_pdc_ret), %rp201bv (%r3)202copy %r0,%arg3203204stext_pdc_ret:205/* restore rfi target address*/206ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10207tophys_r1 %r10208ldd TASK_PT_GR11(%r10), %r11209tovirt_r1 %sp210#endif211212/* PARANOID: clear user scratch/user space SR's */213mtsp %r0,%sr0214mtsp %r0,%sr1215mtsp %r0,%sr2216mtsp %r0,%sr3217218/* Initialize Protection Registers */219mtctl %r0,%cr8220mtctl %r0,%cr9221mtctl %r0,%cr12222mtctl %r0,%cr13223224/* Initialize the global data pointer */225loadgp226227/* Set up our interrupt table. HPMCs might not work after this!228*229* We need to install the correct iva for PA1.1 or PA2.0. The230* following short sequence of instructions can determine this231* (without being illegal on a PA1.1 machine).232*/233#ifndef CONFIG_64BIT234ldi 32,%r10235mtctl %r10,%cr11236.level 2.0237mfctl,w %cr11,%r10238.level 1.1239comib,<>,n 0,%r10,$is_pa20240ldil L%PA(fault_vector_11),%r10241b $install_iva242ldo R%PA(fault_vector_11)(%r10),%r10243244$is_pa20:245.level LEVEL /* restore 1.1 || 2.0w */246#endif /*!CONFIG_64BIT*/247load32 PA(fault_vector_20),%r10248249$install_iva:250mtctl %r10,%cr14251252b aligned_rfi /* Prepare to RFI! Man all the cannons! */253nop254255.align 128256aligned_rfi:257pcxt_ssm_bug258259rsm PSW_SM_QUIET,%r0 /* off troublesome PSW bits */260/* Don't need NOPs, have 8 compliant insn before rfi */261262mtctl %r0,%cr17 /* Clear IIASQ tail */263mtctl %r0,%cr17 /* Clear IIASQ head */264265/* Load RFI target into PC queue */266mtctl %r11,%cr18 /* IIAOQ head */267ldo 4(%r11),%r11268mtctl %r11,%cr18 /* IIAOQ tail */269270load32 KERNEL_PSW,%r10271mtctl %r10,%ipsw272273/* Jump through hyperspace to Virt Mode */274rfi275nop276277.procend278279#ifdef CONFIG_SMP280281.import smp_init_current_idle_task,data282.import smp_callin,code283284#ifndef CONFIG_64BIT285smp_callin_rtn:286.proc287.callinfo288break 1,1 /* Break if returned from start_secondary */289nop290nop291.procend292#endif /*!CONFIG_64BIT*/293294/***************************************************************************295* smp_slave_stext is executed by all non-monarch Processors when the Monarch296* pokes the slave CPUs in smp.c:smp_boot_cpus().297*298* Once here, registers values are initialized in order to branch to virtual299* mode. Once all available/eligible CPUs are in virtual mode, all are300* released and start out by executing their own idle task.301*****************************************************************************/302smp_slave_stext:303.proc304.callinfo305306/*307** Initialize Space registers308*/309mtsp %r0,%sr4310mtsp %r0,%sr5311mtsp %r0,%sr6312mtsp %r0,%sr7313314/* Initialize the SP - monarch sets up smp_init_current_idle_task */315load32 PA(smp_init_current_idle_task),%sp316LDREG 0(%sp),%sp /* load task address */317tophys_r1 %sp318LDREG TASK_THREAD_INFO(%sp),%sp319mtctl %sp,%cr30 /* store in cr30 */320ldo THREAD_SZ_ALGN(%sp),%sp321322/* point CPU to kernel page tables */323load32 PA(swapper_pg_dir),%r4324mtctl %r4,%cr24 /* Initialize kernel root pointer */325mtctl %r4,%cr25 /* Initialize user root pointer */326327#ifdef CONFIG_64BIT328/* Setup PDCE_PROC entry */329copy %arg0,%r3330#else331/* Load RFI *return* address in case smp_callin bails */332load32 smp_callin_rtn,%r2333#endif334335/* Load RFI target address. */336load32 smp_callin,%r11337338/* ok...common code can handle the rest */339b common_stext340nop341342.procend343#endif /* CONFIG_SMP */344345ENDPROC(stext)346347#ifndef CONFIG_64BIT348.section .data..read_mostly349350.align 4351.export $global$,data352353.type $global$,@object354.size $global$,4355$global$:356.word 0357#endif /*!CONFIG_64BIT*/358359360