X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=arch%2Fmips%2Fkernel%2Fhead.S;h=9a7811d13db2ac607439bd238968a6f17a87841c;hb=refs%2Fheads%2Fvserver;hp=89a8456d9de3afabf2a746946db2e359f6b93751;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 89a8456d9..9a7811d13 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -5,7 +5,7 @@ * * Copyright (C) 1994, 1995 Waldorf Electronics * Written by Ralf Baechle and Andreas Busse - * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 Ralf Baechle + * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle * Copyright (C) 1996 Paul M. Antoine * Modified for DECStation and hence R3000 support by Paul M. Antoine * Further modifications by David S. Miller and Harald Koerfgen @@ -13,20 +13,18 @@ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ -#include #include #include #include +#include +#include #include #include #include #include -#ifdef CONFIG_SGI_IP27 -#include -#include -#include -#endif + +#include .macro ARC64_TWIDDLE_PC #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL) @@ -38,18 +36,6 @@ #endif .endm -#ifdef CONFIG_SGI_IP27 - /* - * outputs the local nasid into res. IP27 stuff. - */ - .macro GET_NASID_ASM res - dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID) - ld \res, (\res) - and \res, NSRI_NODEID_MASK - dsrl \res, NSRI_NODEID_SHFT - .endm -#endif /* CONFIG_SGI_IP27 */ - /* * inputs are the text nasid in t1, data nasid in t2. */ @@ -90,15 +76,56 @@ .endm /* - * For the moment set ST0_KU so the CPU will not spit fire when - * executing 64-bit instructions. The full initialization of the - * CPU's status register is done later in per_cpu_trap_init(). + * For the moment disable interrupts, mark the kernel mode and + * set ST0_KX so that the CPU does not spit fire when using + * 64-bit addresses. A full initialization of the CPU's status + * register is done later in per_cpu_trap_init(). */ - .macro setup_c0_status -#ifdef CONFIG_MIPS64 + .macro setup_c0_status set clr + .set push +#ifdef CONFIG_MIPS_MT_SMTC + /* + * For SMTC, we need to set privilege and disable interrupts only for + * the current TC, using the TCStatus register. + */ + mfc0 t0, CP0_TCSTATUS + /* Fortunately CU 0 is in the same place in both registers */ + /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ + li t1, ST0_CU0 | 0x08001c00 + or t0, t1 + /* Clear TKSU, leave IXMT */ + xori t0, 0x00001800 + mtc0 t0, CP0_TCSTATUS + _ehb + /* We need to leave the global IE bit set, but clear EXL...*/ + mfc0 t0, CP0_STATUS + or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr + xor t0, ST0_EXL | ST0_ERL | \clr + mtc0 t0, CP0_STATUS +#else mfc0 t0, CP0_STATUS - or t0, ST0_KX + or t0, ST0_CU0|\set|0x1f|\clr + xor t0, 0x1f|\clr mtc0 t0, CP0_STATUS + .set noreorder + sll zero,3 # ehb +#endif + .set pop + .endm + + .macro setup_c0_status_pri +#ifdef CONFIG_64BIT + setup_c0_status ST0_KX 0 +#else + setup_c0_status 0 0 +#endif + .endm + + .macro setup_c0_status_sec +#ifdef CONFIG_64BIT + setup_c0_status ST0_KX ST0_BEV +#else + setup_c0_status 0 ST0_BEV #endif .endm @@ -111,20 +138,41 @@ EXPORT(stext) # used for profiling EXPORT(_stext) +#ifdef CONFIG_MIPS_SIM + /* + * Give us a fighting chance of running if execution beings at the + * kernel load address. This is needed because this platform does + * not have a ELF loader yet. + */ + j kernel_entry +#endif __INIT NESTED(kernel_entry, 16, sp) # kernel entry point - setup_c0_status -#ifdef CONFIG_SGI_IP27 - GET_NASID_ASM t1 - move t2, t1 # text and data are here - MAPPED_KERNEL_SETUP_TLB -#endif /* IP27 */ + kernel_entry_setup # cpu specific setup + + setup_c0_status_pri ARC64_TWIDDLE_PC - CLI # disable interrupts +#ifdef CONFIG_MIPS_MT_SMTC + /* + * In SMTC kernel, "CLI" is thread-specific, in TCStatus. + * We still need to enable interrupts globally in Status, + * and clear EXL/ERL. + * + * TCContext is used to track interrupt levels under + * service in SMTC kernel. Clear for boot TC before + * allowing any interrupts. + */ + mtc0 zero, CP0_TCCONTEXT + + mfc0 t0, CP0_STATUS + ori t0, t0, 0xff1f + xori t0, t0, 0x001e + mtc0 t0, CP0_STATUS +#endif /* CONFIG_MIPS_MT_SMTC */ PTR_LA t0, __bss_start # clear .bss LONG_S zero, (t0) @@ -139,36 +187,46 @@ NESTED(kernel_entry, 16, sp) # kernel entry point LONG_S a2, fw_arg2 LONG_S a3, fw_arg3 + MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_ADDIU sp, $28, _THREAD_SIZE - 32 + PTR_LI sp, _THREAD_SIZE - 32 + PTR_ADDU sp, $28 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer - jal start_kernel + j start_kernel END(kernel_entry) +#ifdef CONFIG_QEMU + __INIT +#endif + #ifdef CONFIG_SMP /* * SMP slave cpus entry point. Board specific code for bootstrap calls this * function after setting up the stack and gp registers. */ NESTED(smp_bootstrap, 16, sp) -#ifdef CONFIG_SGI_IP27 - GET_NASID_ASM t1 - dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ - KLDIR_OFF_POINTER + CAC_BASE - dsll t1, NASID_SHFT - or t0, t0, t1 - ld t0, 0(t0) # t0 points to kern_vars struct - lh t1, KV_RO_NASID_OFFSET(t0) - lh t2, KV_RW_NASID_OFFSET(t0) - MAPPED_KERNEL_SETUP_TLB - ARC64_TWIDDLE_PC -#endif /* CONFIG_SGI_IP27 */ - - CLI - setup_c0_status - jal start_secondary +#ifdef CONFIG_MIPS_MT_SMTC + /* + * Read-modify-writes of Status must be atomic, and this + * is one case where CLI is invoked without EXL being + * necessarily set. The CLI and setup_c0_status will + * in fact be redundant for all but the first TC of + * each VPE being booted. + */ + DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */ + jal mips_ihb +#endif /* CONFIG_MIPS_MT_SMTC */ + setup_c0_status_sec + smp_slave_setup +#ifdef CONFIG_MIPS_MT_SMTC + andi t2, t2, VPECONTROL_TE + beqz t2, 2f + EMT # emt +2: +#endif /* CONFIG_MIPS_MT_SMTC */ + j start_secondary END(smp_bootstrap) #endif /* CONFIG_SMP */ @@ -182,32 +240,19 @@ NESTED(smp_bootstrap, 16, sp) .comm fw_arg2, SZREG, SZREG .comm fw_arg3, SZREG, SZREG - .macro page name, order=0 - .globl \name -\name: .size \name, (_PAGE_SIZE << \order) - .org . + (_PAGE_SIZE << \order) - .type \name, @object + .macro page name, order + .comm \name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order) .endm - .data - .align PAGE_SHIFT - /* - * ... but on 64-bit we've got three-level pagetables with a - * slightly different layout ... + * On 64-bit we've got three-level pagetables with a slightly + * different layout ... */ page swapper_pg_dir, _PGD_ORDER -#ifdef CONFIG_MIPS64 +#ifdef CONFIG_64BIT +#if defined(CONFIG_MODULES) && !defined(CONFIG_BUILD_ELF64) + page module_pg_dir, _PGD_ORDER +#endif page invalid_pmd_table, _PMD_ORDER #endif page invalid_pte_table, _PTE_ORDER - -#ifdef CONFIG_MIPS64 - /* - * 64-bit kernel mappings are really screwed up ... - */ - page kptbl, _PGD_ORDER - .globl ekptbl - page kpmdtbl, 0 -ekptbl: -#endif