diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2010-10-14 16:23:03 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-10-15 15:38:09 -0400 |
commit | a78c942df64ef4cf495fd4d8715e48501bd7f8a4 (patch) | |
tree | fe44212d36e6ca23dbe9f2c633824389216a3d1d /arch/tile | |
parent | bf65e440e8248f22b2eacf8d47961bb9d52260f7 (diff) |
arch/tile: parameterize system PLs to support KVM port
While not a port to KVM (yet), this change modifies the kernel
to be able to build either at PL1 or at PL2 with a suitable
config switch. Pushing up this change avoids handling branch
merge issues going forward with the KVM work.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r-- | arch/tile/Kconfig | 12 | ||||
-rw-r--r-- | arch/tile/Makefile | 2 | ||||
-rw-r--r-- | arch/tile/include/arch/spr_def.h | 85 | ||||
-rw-r--r-- | arch/tile/include/arch/spr_def_32.h | 39 | ||||
-rw-r--r-- | arch/tile/include/asm/irqflags.h | 64 | ||||
-rw-r--r-- | arch/tile/include/asm/page.h | 27 | ||||
-rw-r--r-- | arch/tile/include/asm/processor.h | 11 | ||||
-rw-r--r-- | arch/tile/include/asm/ptrace.h | 4 | ||||
-rw-r--r-- | arch/tile/include/asm/system.h | 2 | ||||
-rw-r--r-- | arch/tile/include/hv/hypervisor.h | 30 | ||||
-rw-r--r-- | arch/tile/kernel/entry.S | 12 | ||||
-rw-r--r-- | arch/tile/kernel/head_32.S | 5 | ||||
-rw-r--r-- | arch/tile/kernel/intvec_32.S | 67 | ||||
-rw-r--r-- | arch/tile/kernel/irq.c | 16 | ||||
-rw-r--r-- | arch/tile/kernel/messaging.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/process.c | 12 | ||||
-rw-r--r-- | arch/tile/kernel/regs_32.S | 2 | ||||
-rw-r--r-- | arch/tile/kernel/setup.c | 28 | ||||
-rw-r--r-- | arch/tile/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/tile/kvm/Kconfig | 38 | ||||
-rw-r--r-- | arch/tile/mm/fault.c | 6 | ||||
-rw-r--r-- | arch/tile/mm/init.c | 2 |
23 files changed, 338 insertions, 132 deletions
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 2361e3e80bd..89cfee07efa 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -96,6 +96,7 @@ config HVC_TILE config TILE def_bool y + select HAVE_KVM if !TILEGX select GENERIC_FIND_FIRST_BIT select GENERIC_FIND_NEXT_BIT select USE_GENERIC_SMP_HELPERS @@ -314,6 +315,15 @@ config HARDWALL bool "Hardwall support to allow access to user dynamic network" default y +config KERNEL_PL + int "Processor protection level for kernel" + range 1 2 + default "1" + ---help--- + This setting determines the processor protection level the + kernel will be built to run at. Generally you should use + the default value here. + endmenu # Tilera-specific configuration menu "Bus options" @@ -354,3 +364,5 @@ source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" + +source "arch/tile/kvm/Kconfig" diff --git a/arch/tile/Makefile b/arch/tile/Makefile index a700f7f6cf5..17acce70569 100644 --- a/arch/tile/Makefile +++ b/arch/tile/Makefile @@ -53,6 +53,8 @@ libs-y += $(LIBGCC_PATH) # See arch/tile/Kbuild for content of core part of the kernel core-y += arch/tile/ +core-$(CONFIG_KVM) += arch/tile/kvm/ + ifdef TILERA_ROOT INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot endif diff --git a/arch/tile/include/arch/spr_def.h b/arch/tile/include/arch/spr_def.h index c8fdbd9a45e..442fcba0d12 100644 --- a/arch/tile/include/arch/spr_def.h +++ b/arch/tile/include/arch/spr_def.h @@ -12,8 +12,93 @@ * more details. */ +/* + * In addition to including the proper base SPR definition file, depending + * on machine architecture, this file defines several macros which allow + * kernel code to use protection-level dependent SPRs without worrying + * about which PL it's running at. In these macros, the PL that the SPR + * or interrupt number applies to is replaced by K. + */ + +#if CONFIG_KERNEL_PL != 1 && CONFIG_KERNEL_PL != 2 +#error CONFIG_KERNEL_PL must be 1 or 2 +#endif + +/* Concatenate 4 strings. */ +#define __concat4(a, b, c, d) a ## b ## c ## d +#define _concat4(a, b, c, d) __concat4(a, b, c, d) + #ifdef __tilegx__ #include <arch/spr_def_64.h> + +/* TILE-Gx dependent, protection-level dependent SPRs. */ + +#define SPR_INTERRUPT_MASK_K \ + _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL,,) +#define SPR_INTERRUPT_MASK_SET_K \ + _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL,,) +#define SPR_INTERRUPT_MASK_RESET_K \ + _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL,,) +#define SPR_INTERRUPT_VECTOR_BASE_K \ + _concat4(SPR_INTERRUPT_VECTOR_BASE_, CONFIG_KERNEL_PL,,) + +#define SPR_IPI_MASK_K \ + _concat4(SPR_IPI_MASK_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_MASK_RESET_K \ + _concat4(SPR_IPI_MASK_RESET_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_MASK_SET_K \ + _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_EVENT_K \ + _concat4(SPR_IPI_EVENT_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_EVENT_RESET_K \ + _concat4(SPR_IPI_EVENT_RESET_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_MASK_SET_K \ + _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,) +#define INT_IPI_K \ + _concat4(INT_IPI_, CONFIG_KERNEL_PL,,) + +#define SPR_SINGLE_STEP_CONTROL_K \ + _concat4(SPR_SINGLE_STEP_CONTROL_, CONFIG_KERNEL_PL,,) +#define SPR_SINGLE_STEP_EN_K_K \ + _concat4(SPR_SINGLE_STEP_EN_, CONFIG_KERNEL_PL, _, CONFIG_KERNEL_PL) +#define INT_SINGLE_STEP_K \ + _concat4(INT_SINGLE_STEP_, CONFIG_KERNEL_PL,,) + #else #include <arch/spr_def_32.h> + +/* TILEPro dependent, protection-level dependent SPRs. */ + +#define SPR_INTERRUPT_MASK_K_0 \ + _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL, _0,) +#define SPR_INTERRUPT_MASK_K_1 \ + _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL, _1,) +#define SPR_INTERRUPT_MASK_SET_K_0 \ + _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL, _0,) +#define SPR_INTERRUPT_MASK_SET_K_1 \ + _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL, _1,) +#define SPR_INTERRUPT_MASK_RESET_K_0 \ + _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL, _0,) +#define SPR_INTERRUPT_MASK_RESET_K_1 \ + _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL, _1,) + #endif + +/* Generic protection-level dependent SPRs. */ + +#define SPR_SYSTEM_SAVE_K_0 \ + _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _0,) +#define SPR_SYSTEM_SAVE_K_1 \ + _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _1,) +#define SPR_SYSTEM_SAVE_K_2 \ + _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _2,) +#define SPR_SYSTEM_SAVE_K_3 \ + _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _3,) +#define SPR_EX_CONTEXT_K_0 \ + _concat4(SPR_EX_CONTEXT_, CONFIG_KERNEL_PL, _0,) +#define SPR_EX_CONTEXT_K_1 \ + _concat4(SPR_EX_CONTEXT_, CONFIG_KERNEL_PL, _1,) +#define SPR_INTCTRL_K_STATUS \ + _concat4(SPR_INTCTRL_, CONFIG_KERNEL_PL, _STATUS,) +#define INT_INTCTRL_K \ + _concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,) diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/arch/spr_def_32.h index b4fc06864df..bbc1f4c924e 100644 --- a/arch/tile/include/arch/spr_def_32.h +++ b/arch/tile/include/arch/spr_def_32.h @@ -56,58 +56,93 @@ #define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2 #define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1 #define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4 +#define SPR_EX_CONTEXT_2_0 0x4605 +#define SPR_EX_CONTEXT_2_1 0x4606 +#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0 +#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3 +#define SPR_EX_CONTEXT_2_1__PL_MASK 0x3 +#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2 +#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1 +#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4 #define SPR_FAIL 0x4e09 #define SPR_INTCTRL_0_STATUS 0x4a07 #define SPR_INTCTRL_1_STATUS 0x4807 +#define SPR_INTCTRL_2_STATUS 0x4607 #define SPR_INTERRUPT_CRITICAL_SECTION 0x4e0a #define SPR_INTERRUPT_MASK_0_0 0x4a08 #define SPR_INTERRUPT_MASK_0_1 0x4a09 #define SPR_INTERRUPT_MASK_1_0 0x4809 #define SPR_INTERRUPT_MASK_1_1 0x480a +#define SPR_INTERRUPT_MASK_2_0 0x4608 +#define SPR_INTERRUPT_MASK_2_1 0x4609 #define SPR_INTERRUPT_MASK_RESET_0_0 0x4a0a #define SPR_INTERRUPT_MASK_RESET_0_1 0x4a0b #define SPR_INTERRUPT_MASK_RESET_1_0 0x480b #define SPR_INTERRUPT_MASK_RESET_1_1 0x480c +#define SPR_INTERRUPT_MASK_RESET_2_0 0x460a +#define SPR_INTERRUPT_MASK_RESET_2_1 0x460b #define SPR_INTERRUPT_MASK_SET_0_0 0x4a0c #define SPR_INTERRUPT_MASK_SET_0_1 0x4a0d #define SPR_INTERRUPT_MASK_SET_1_0 0x480d #define SPR_INTERRUPT_MASK_SET_1_1 0x480e +#define SPR_INTERRUPT_MASK_SET_2_0 0x460c +#define SPR_INTERRUPT_MASK_SET_2_1 0x460d #define SPR_MPL_DMA_CPL_SET_0 0x5800 #define SPR_MPL_DMA_CPL_SET_1 0x5801 +#define SPR_MPL_DMA_CPL_SET_2 0x5802 #define SPR_MPL_DMA_NOTIFY_SET_0 0x3800 #define SPR_MPL_DMA_NOTIFY_SET_1 0x3801 +#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802 #define SPR_MPL_INTCTRL_0_SET_0 0x4a00 #define SPR_MPL_INTCTRL_0_SET_1 0x4a01 +#define SPR_MPL_INTCTRL_0_SET_2 0x4a02 #define SPR_MPL_INTCTRL_1_SET_0 0x4800 #define SPR_MPL_INTCTRL_1_SET_1 0x4801 +#define SPR_MPL_INTCTRL_1_SET_2 0x4802 +#define SPR_MPL_INTCTRL_2_SET_0 0x4600 +#define SPR_MPL_INTCTRL_2_SET_1 0x4601 +#define SPR_MPL_INTCTRL_2_SET_2 0x4602 #define SPR_MPL_SN_ACCESS_SET_0 0x0800 #define SPR_MPL_SN_ACCESS_SET_1 0x0801 +#define SPR_MPL_SN_ACCESS_SET_2 0x0802 #define SPR_MPL_SN_CPL_SET_0 0x5a00 #define SPR_MPL_SN_CPL_SET_1 0x5a01 +#define SPR_MPL_SN_CPL_SET_2 0x5a02 #define SPR_MPL_SN_FIREWALL_SET_0 0x2c00 #define SPR_MPL_SN_FIREWALL_SET_1 0x2c01 +#define SPR_MPL_SN_FIREWALL_SET_2 0x2c02 #define SPR_MPL_SN_NOTIFY_SET_0 0x2a00 #define SPR_MPL_SN_NOTIFY_SET_1 0x2a01 +#define SPR_MPL_SN_NOTIFY_SET_2 0x2a02 #define SPR_MPL_UDN_ACCESS_SET_0 0x0c00 #define SPR_MPL_UDN_ACCESS_SET_1 0x0c01 +#define SPR_MPL_UDN_ACCESS_SET_2 0x0c02 #define SPR_MPL_UDN_AVAIL_SET_0 0x4000 #define SPR_MPL_UDN_AVAIL_SET_1 0x4001 +#define SPR_MPL_UDN_AVAIL_SET_2 0x4002 #define SPR_MPL_UDN_CA_SET_0 0x3c00 #define SPR_MPL_UDN_CA_SET_1 0x3c01 +#define SPR_MPL_UDN_CA_SET_2 0x3c02 #define SPR_MPL_UDN_COMPLETE_SET_0 0x1400 #define SPR_MPL_UDN_COMPLETE_SET_1 0x1401 +#define SPR_MPL_UDN_COMPLETE_SET_2 0x1402 #define SPR_MPL_UDN_FIREWALL_SET_0 0x3000 #define SPR_MPL_UDN_FIREWALL_SET_1 0x3001 +#define SPR_MPL_UDN_FIREWALL_SET_2 0x3002 #define SPR_MPL_UDN_REFILL_SET_0 0x1000 #define SPR_MPL_UDN_REFILL_SET_1 0x1001 +#define SPR_MPL_UDN_REFILL_SET_2 0x1002 #define SPR_MPL_UDN_TIMER_SET_0 0x3600 #define SPR_MPL_UDN_TIMER_SET_1 0x3601 +#define SPR_MPL_UDN_TIMER_SET_2 0x3602 #define SPR_MPL_WORLD_ACCESS_SET_0 0x4e00 #define SPR_MPL_WORLD_ACCESS_SET_1 0x4e01 +#define SPR_MPL_WORLD_ACCESS_SET_2 0x4e02 #define SPR_PASS 0x4e0b #define SPR_PERF_COUNT_0 0x4205 #define SPR_PERF_COUNT_1 0x4206 #define SPR_PERF_COUNT_CTL 0x4207 +#define SPR_PERF_COUNT_DN_CTL 0x4210 #define SPR_PERF_COUNT_STS 0x4208 #define SPR_PROC_STATUS 0x4f00 #define SPR_SIM_CONTROL 0x4e0c @@ -124,6 +159,10 @@ #define SPR_SYSTEM_SAVE_1_1 0x4901 #define SPR_SYSTEM_SAVE_1_2 0x4902 #define SPR_SYSTEM_SAVE_1_3 0x4903 +#define SPR_SYSTEM_SAVE_2_0 0x4700 +#define SPR_SYSTEM_SAVE_2_1 0x4701 +#define SPR_SYSTEM_SAVE_2_2 0x4702 +#define SPR_SYSTEM_SAVE_2_3 0x4703 #define SPR_TILE_COORD 0x4c17 #define SPR_TILE_RTF_HWM 0x4e10 #define SPR_TILE_TIMER_CONTROL 0x3205 diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index 45cf67c2f28..6ebdd7d1e67 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h @@ -47,53 +47,53 @@ int __n = (n); \ int __mask = 1 << (__n & 0x1f); \ if (__n < 32) \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, __mask); \ + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_0, __mask); \ else \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, __mask); \ + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_1, __mask); \ } while (0) #define interrupt_mask_reset(n) do { \ int __n = (n); \ int __mask = 1 << (__n & 0x1f); \ if (__n < 32) \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, __mask); \ + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, __mask); \ else \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, __mask); \ + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, __mask); \ } while (0) #define interrupt_mask_check(n) ({ \ int __n = (n); \ (((__n < 32) ? \ - __insn_mfspr(SPR_INTERRUPT_MASK_1_0) : \ - __insn_mfspr(SPR_INTERRUPT_MASK_1_1)) \ + __insn_mfspr(SPR_INTERRUPT_MASK_K_0) : \ + __insn_mfspr(SPR_INTERRUPT_MASK_K_1)) \ >> (__n & 0x1f)) & 1; \ }) #define interrupt_mask_set_mask(mask) do { \ unsigned long long __m = (mask); \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, (unsigned long)(__m)); \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, (unsigned long)(__m>>32)); \ + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_0, (unsigned long)(__m)); \ + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_1, (unsigned long)(__m>>32)); \ } while (0) #define interrupt_mask_reset_mask(mask) do { \ unsigned long long __m = (mask); \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, (unsigned long)(__m)); \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, (unsigned long)(__m>>32)); \ + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, (unsigned long)(__m)); \ + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, (unsigned long)(__m>>32)); \ } while (0) #else #define interrupt_mask_set(n) \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (1UL << (n))) + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (1UL << (n))) #define interrupt_mask_reset(n) \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (1UL << (n))) + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (1UL << (n))) #define interrupt_mask_check(n) \ - ((__insn_mfspr(SPR_INTERRUPT_MASK_1) >> (n)) & 1) + ((__insn_mfspr(SPR_INTERRUPT_MASK_K) >> (n)) & 1) #define interrupt_mask_set_mask(mask) \ - __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (mask)) + __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (mask)) #define interrupt_mask_reset_mask(mask) \ - __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (mask)) + __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (mask)) #endif /* * The set of interrupts we want active if irqs are enabled. * Note that in particular, the tile timer interrupt comes and goes * from this set, since we have no other way to turn off the timer. - * Likewise, INTCTRL_1 is removed and re-added during device + * Likewise, INTCTRL_K is removed and re-added during device * interrupts, as is the the hardwall UDN_FIREWALL interrupt. * We use a low bit (MEM_ERROR) as our sentinel value and make sure it * is always claimed as an "active interrupt" so we can query that bit @@ -168,14 +168,14 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); /* Return 0 or 1 to indicate whether interrupts are currently disabled. */ #define IRQS_DISABLED(tmp) \ - mfspr tmp, INTERRUPT_MASK_1; \ + mfspr tmp, SPR_INTERRUPT_MASK_K; \ andi tmp, tmp, 1 /* Load up a pointer to &interrupts_enabled_mask. */ #define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \ - moveli reg, hw2_last(interrupts_enabled_mask); \ - shl16insli reg, reg, hw1(interrupts_enabled_mask); \ - shl16insli reg, reg, hw0(interrupts_enabled_mask); \ + moveli reg, hw2_last(interrupts_enabled_mask); \ + shl16insli reg, reg, hw1(interrupts_enabled_mask); \ + shl16insli reg, reg, hw0(interrupts_enabled_mask); \ add reg, reg, tp /* Disable interrupts. */ @@ -183,18 +183,18 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); moveli tmp0, hw2_last(LINUX_MASKABLE_INTERRUPTS); \ shl16insli tmp0, tmp0, hw1(LINUX_MASKABLE_INTERRUPTS); \ shl16insli tmp0, tmp0, hw0(LINUX_MASKABLE_INTERRUPTS); \ - mtspr INTERRUPT_MASK_SET_1, tmp0 + mtspr SPR_INTERRUPT_MASK_SET_K, tmp0 /* Disable ALL synchronous interrupts (used by NMI entry). */ #define IRQ_DISABLE_ALL(tmp) \ movei tmp, -1; \ - mtspr INTERRUPT_MASK_SET_1, tmp + mtspr SPR_INTERRUPT_MASK_SET_K, tmp /* Enable interrupts. */ #define IRQ_ENABLE(tmp0, tmp1) \ GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \ ld tmp0, tmp0; \ - mtspr INTERRUPT_MASK_RESET_1, tmp0 + mtspr SPR_INTERRUPT_MASK_RESET_K, tmp0 #else /* !__tilegx__ */ @@ -208,14 +208,14 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); * (making the original code's write of the "high" mask word idempotent). */ #define IRQS_DISABLED(tmp) \ - mfspr tmp, INTERRUPT_MASK_1_0; \ + mfspr tmp, SPR_INTERRUPT_MASK_K_0; \ shri tmp, tmp, INT_MEM_ERROR; \ andi tmp, tmp, 1 /* Load up a pointer to &interrupts_enabled_mask. */ #define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \ - moveli reg, lo16(interrupts_enabled_mask); \ - auli reg, reg, ha16(interrupts_enabled_mask);\ + moveli reg, lo16(interrupts_enabled_mask); \ + auli reg, reg, ha16(interrupts_enabled_mask); \ add reg, reg, tp /* Disable interrupts. */ @@ -225,16 +225,16 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \ }; \ { \ - mtspr INTERRUPT_MASK_SET_1_0, tmp0; \ + mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \ auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \ }; \ - mtspr INTERRUPT_MASK_SET_1_1, tmp1 + mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1 /* Disable ALL synchronous interrupts (used by NMI entry). */ #define IRQ_DISABLE_ALL(tmp) \ movei tmp, -1; \ - mtspr INTERRUPT_MASK_SET_1_0, tmp; \ - mtspr INTERRUPT_MASK_SET_1_1, tmp + mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp; \ + mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp /* Enable interrupts. */ #define IRQ_ENABLE(tmp0, tmp1) \ @@ -244,8 +244,8 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); addi tmp1, tmp0, 4 \ }; \ lw tmp1, tmp1; \ - mtspr INTERRUPT_MASK_RESET_1_0, tmp0; \ - mtspr INTERRUPT_MASK_RESET_1_1, tmp1 + mtspr SPR_INTERRUPT_MASK_RESET_K_0, tmp0; \ + mtspr SPR_INTERRUPT_MASK_RESET_K_1, tmp1 #endif /* diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h index 7d90641cf18..7979a45430d 100644 --- a/arch/tile/include/asm/page.h +++ b/arch/tile/include/asm/page.h @@ -199,17 +199,17 @@ static inline __attribute_const__ int get_order(unsigned long size) * If you want more physical memory than this then see the CONFIG_HIGHMEM * option in the kernel configuration. * - * The top two 16MB chunks in the table below (VIRT and HV) are - * unavailable to Linux. Since the kernel interrupt vectors must live - * at 0xfd000000, we map all of the bottom of RAM at this address with - * a huge page table entry to minimize its ITLB footprint (as well as - * at PAGE_OFFSET). The last architected requirement is that user - * interrupt vectors live at 0xfc000000, so we make that range of - * memory available to user processes. The remaining regions are sized - * as shown; after the first four addresses, we show "typical" values, - * since the actual addresses depend on kernel #defines. + * The top 16MB chunk in the table below is unavailable to Linux. Since + * the kernel interrupt vectors must live at ether 0xfe000000 or 0xfd000000 + * (depending on whether the kernel is at PL2 or Pl1), we map all of the + * bottom of RAM at this address with a huge page table entry to minimize + * its ITLB footprint (as well as at PAGE_OFFSET). The last architected + * requirement is that user interrupt vectors live at 0xfc000000, so we + * make that range of memory available to user processes. The remaining + * regions are sized as shown; the first four addresses use the PL 1 + * values, and after that, we show "typical" values, since the actual + * addresses depend on kernel #defines. * - * MEM_VIRT_INTRPT 0xff000000 * MEM_HV_INTRPT 0xfe000000 * MEM_SV_INTRPT (kernel code) 0xfd000000 * MEM_USER_INTRPT (user vector) 0xfc000000 @@ -221,9 +221,14 @@ static inline __attribute_const__ int get_order(unsigned long size) */ #define MEM_USER_INTRPT _AC(0xfc000000, UL) +#if CONFIG_KERNEL_PL == 1 #define MEM_SV_INTRPT _AC(0xfd000000, UL) #define MEM_HV_INTRPT _AC(0xfe000000, UL) -#define MEM_VIRT_INTRPT _AC(0xff000000, UL) +#else +#define MEM_GUEST_INTRPT _AC(0xfd000000, UL) +#define MEM_SV_INTRPT _AC(0xfe000000, UL) +#define MEM_HV_INTRPT _AC(0xff000000, UL) +#endif #define INTRPT_SIZE 0x4000 diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index ccd5f842568..1747ff3946b 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h @@ -328,18 +328,21 @@ extern int kdata_huge; * Note that assembly code assumes that USER_PL is zero. */ #define USER_PL 0 -#define KERNEL_PL 1 +#if CONFIG_KERNEL_PL == 2 +#define GUEST_PL 1 +#endif +#define KERNEL_PL CONFIG_KERNEL_PL -/* SYSTEM_SAVE_1_0 holds the current cpu number ORed with ksp0. */ +/* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */ #define CPU_LOG_MASK_VALUE 12 #define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1) #if CONFIG_NR_CPUS > CPU_MASK_VALUE # error Too many cpus! #endif #define raw_smp_processor_id() \ - ((int)__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & CPU_MASK_VALUE) + ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & CPU_MASK_VALUE) #define get_current_ksp0() \ - (__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & ~CPU_MASK_VALUE) + (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~CPU_MASK_VALUE) #define next_current_ksp0(task) ({ \ unsigned long __ksp0 = task_ksp0(task); \ int __cpu = raw_smp_processor_id(); \ diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index 4a02bb07397..ac6d343129d 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h @@ -62,8 +62,8 @@ struct pt_regs { pt_reg_t lr; /* aliases regs[TREG_LR] */ /* Saved special registers. */ - pt_reg_t pc; /* stored in EX_CONTEXT_1_0 */ - pt_reg_t ex1; /* stored in EX_CONTEXT_1_1 (PL and ICS bit) */ + pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */ + pt_reg_t ex1; /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */ pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */ pt_reg_t orig_r0; /* r0 at syscall entry, else zero */ pt_reg_t flags; /* flags (see below) */ diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h index fb7ff9574d7..5388850deeb 100644 --- a/arch/tile/include/asm/system.h +++ b/arch/tile/include/asm/system.h @@ -164,7 +164,7 @@ extern struct task_struct *_switch_to(struct task_struct *prev, /* Helper function for _switch_to(). */ extern struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next, - unsigned long new_system_save_1_0); + unsigned long new_system_save_k_0); /* Address that switched-away from tasks are at. */ extern unsigned long get_switch_to_pc(void); diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h index 9bd303a141b..f672544cd4f 100644 --- a/arch/tile/include/hv/hypervisor.h +++ b/arch/tile/include/hv/hypervisor.h @@ -1003,37 +1003,37 @@ int hv_console_write(HV_VirtAddr bytes, int len); * when these occur in a client's interrupt critical section, they must * be delivered through the downcall mechanism. * - * A downcall is initially delivered to the client as an INTCTRL_1 - * interrupt. Upon entry to the INTCTRL_1 vector, the client must - * immediately invoke the hv_downcall_dispatch service. This service - * will not return; instead it will cause one of the client's actual - * downcall-handling interrupt vectors to be entered. The EX_CONTEXT - * registers in the client will be set so that when the client irets, - * it will return to the code which was interrupted by the INTCTRL_1 - * interrupt. - * - * Under some circumstances, the firing of INTCTRL_1 can race with + * A downcall is initially delivered to the client as an INTCTRL_CL + * interrupt, where CL is the client's PL. Upon entry to the INTCTRL_CL + * vector, the client must immediately invoke the hv_downcall_dispatch + * service. This service will not return; instead it will cause one of + * the client's actual downcall-handling interrupt vectors to be entered. + * The EX_CONTEXT registers in the client will be set so that when the + * client irets, it will return to the code which was interrupted by the + * INTCTRL_CL interrupt. + * + * Under some circumstances, the firing of INTCTRL_CL can race with * the lowering of a device interrupt. In such a case, the * hv_downcall_dispatch service may issue an iret instruction instead * of entering one of the client's actual downcall-handling interrupt * vectors. This will return execution to the location that was - * interrupted by INTCTRL_1. + * interrupted by INTCTRL_CL. * * Any saving of registers should be done by the actual handling - * vectors; no registers should be changed by the INTCTRL_1 handler. + * vectors; no registers should be changed by the INTCTRL_CL handler. * In particular, the client should not use a jal instruction to invoke * the hv_downcall_dispatch service, as that would overwrite the client's * lr register. Note that the hv_downcall_dispatch service may overwrite * one or more of the client's system save registers. * - * The client must not modify the INTCTRL_1_STATUS SPR. The hypervisor + * The client must not modify the INTCTRL_CL_STATUS SPR. The hypervisor * will set this register to cause a downcall to happen, and will clear * it when no further downcalls are pending. * - * When a downcall vector is entered, the INTCTRL_1 interrupt will be + * When a downcall vector is entered, the INTCTRL_CL interrupt will be * masked. When the client is done processing a downcall, and is ready * to accept another, it must unmask this interrupt; if more downcalls - * are pending, this will cause the INTCTRL_1 vector to be reentered. + * are pending, this will cause the INTCTRL_CL vector to be reentered. * Currently the following interrupt vectors can be entered through a * downcall: * diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S index 80d13f013bb..fd8dc42abdc 100644 --- a/arch/tile/kernel/entry.S +++ b/arch/tile/kernel/entry.S @@ -15,7 +15,9 @@ #include <linux/linkage.h> #include <linux/unistd.h> #include <asm/irqflags.h> +#include <asm/processor.h> #include <arch/abi.h> +#include <arch/spr_def.h> #ifdef __tilegx__ #define bnzt bnezt @@ -80,7 +82,7 @@ STD_ENTRY(KBacktraceIterator_init_current) STD_ENTRY(cpu_idle_on_new_stack) { move sp, r1 - mtspr SYSTEM_SAVE_1_0, r2 + mtspr SPR_SYSTEM_SAVE_K_0, r2 } jal free_thread_info j cpu_idle @@ -102,15 +104,15 @@ STD_ENTRY(smp_nap) STD_ENTRY(_cpu_idle) { lnk r0 - movei r1, 1 + movei r1, KERNEL_PL } { addli r0, r0, _cpu_idle_nap - . mtspr INTERRUPT_CRITICAL_SECTION, r1 } - IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */ - mtspr EX_CONTEXT_1_1, r1 /* PL1, ICS clear */ - mtspr EX_CONTEXT_1_0, r0 + IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */ + mtspr SPR_EX_CONTEXT_K_1, r1 /* Kernel PL, ICS clear */ + mtspr SPR_EX_CONTEXT_K_0, r0 iret .global _cpu_idle_nap _cpu_idle_nap: diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S index 2b4f6c09170..90e7c443569 100644 --- a/arch/tile/kernel/head_32.S +++ b/arch/tile/kernel/head_32.S @@ -23,6 +23,7 @@ #include <asm/asm-offsets.h> #include <hv/hypervisor.h> #include <arch/chip.h> +#include <arch/spr_def.h> /* * This module contains the entry code for kernel images. It performs the @@ -76,7 +77,7 @@ ENTRY(_start) } 1: - /* Get our processor number and save it away in SAVE_1_0. */ + /* Get our processor number and save it away in SAVE_K_0. */ jal hv_inquire_topology mulll_uu r4, r1, r2 /* r1 == y, r2 == width */ add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */ @@ -124,7 +125,7 @@ ENTRY(_start) lw r0, r0 lw sp, r1 or r4, sp, r4 - mtspr SYSTEM_SAVE_1_0, r4 /* save ksp0 + cpu */ + mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */ addi sp, sp, -STACK_TOP_DELTA { move lr, zero /* stop backtraces in the called function */ diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f87c5c044d6..206dc7e1fe3 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -32,8 +32,8 @@ # error "No support for kernel preemption currently" #endif -#if INT_INTCTRL_1 < 32 || INT_INTCTRL_1 >= 48 -# error INT_INTCTRL_1 coded to set high interrupt mask +#if INT_INTCTRL_K < 32 || INT_INTCTRL_K >= 48 +# error INT_INTCTRL_K coded to set high interrupt mask #endif #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) @@ -132,8 +132,8 @@ intvec_\vecname: /* Temporarily save a register so we have somewhere to work. */ - mtspr SYSTEM_SAVE_1_1, r0 - mfspr r0, EX_CONTEXT_1_1 + mtspr SPR_SYSTEM_SAVE_K_1, r0 + mfspr r0, SPR_EX_CONTEXT_K_1 /* The cmpxchg code clears sp to force us to reset it here on fault. */ { @@ -167,18 +167,18 @@ intvec_\vecname: * The page_fault handler may be downcalled directly by the * hypervisor even when Linux is running and has ICS set. * - * In this case the contents of EX_CONTEXT_1_1 reflect the + * In this case the contents of EX_CONTEXT_K_1 reflect the * previous fault and can't be relied on to choose whether or * not to reinitialize the stack pointer. So we add a test - * to see whether SYSTEM_SAVE_1_2 has the high bit set, + * to see whether SYSTEM_SAVE_K_2 has the high bit set, * and if so we don't reinitialize sp, since we must be coming * from Linux. (In fact the precise case is !(val & ~1), * but any Linux PC has to have the high bit set.) * - * Note that the hypervisor *always* sets SYSTEM_SAVE_1_2 for + * Note that the hypervisor *always* sets SYSTEM_SAVE_K_2 for * any path that turns into a downcall to one of our TLB handlers. */ - mfspr r0, SYSTEM_SAVE_1_2 + mfspr r0, SPR_SYSTEM_SAVE_K_2 { blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */ move r0, sp @@ -187,12 +187,12 @@ intvec_\vecname: 2: /* - * SYSTEM_SAVE_1_0 holds the cpu number in the low bits, and + * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and * the current stack top in the higher bits. So we recover * our stack top by just masking off the low bits, then * point sp at the top aligned address on the actual stack page. */ - mfspr r0, SYSTEM_SAVE_1_0 + mfspr r0, SPR_SYSTEM_SAVE_K_0 mm r0, r0, zero, LOG2_THREAD_SIZE, 31 0: @@ -254,7 +254,7 @@ intvec_\vecname: sw sp, r3 addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3) } - mfspr r0, EX_CONTEXT_1_0 + mfspr r0, SPR_EX_CONTEXT_K_0 .ifc \processing,handle_syscall /* * Bump the saved PC by one bundle so that when we return, we won't @@ -267,7 +267,7 @@ intvec_\vecname: sw sp, r0 addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC } - mfspr r0, EX_CONTEXT_1_1 + mfspr r0, SPR_EX_CONTEXT_K_1 { sw sp, r0 addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1 @@ -289,7 +289,7 @@ intvec_\vecname: .endif addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM } - mfspr r0, SYSTEM_SAVE_1_1 /* Original r0 */ + mfspr r0, SPR_SYSTEM_SAVE_K_1 /* Original r0 */ { sw sp, r0 addi sp, sp, -PTREGS_OFFSET_REG(0) - 4 @@ -309,12 +309,12 @@ intvec_\vecname: * See discussion below at "finish_interrupt_save". */ .ifc \c_routine, do_page_fault - mfspr r2, SYSTEM_SAVE_1_3 /* address of page fault */ - mfspr r3, SYSTEM_SAVE_1_2 /* info about page fault */ + mfspr r2, SPR_SYSTEM_SAVE_K_3 /* address of page fault */ + mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */ .else .ifc \vecnum, INT_DOUBLE_FAULT { - mfspr r2, SYSTEM_SAVE_1_2 /* double fault info from HV */ + mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */ movei r3, 0 } .else @@ -467,7 +467,7 @@ intvec_\vecname: /* Load tp with our per-cpu offset. */ #ifdef CONFIG_SMP { - mfspr r20, SYSTEM_SAVE_1_0 + mfspr r20, SPR_SYSTEM_SAVE_K_0 moveli r21, lo16(__per_cpu_offset) } { @@ -487,7 +487,7 @@ intvec_\vecname: * We load flags in r32 here so we can jump to .Lrestore_regs |