summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh5
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh5')
-rw-r--r--arch/sh/kernel/cpu/sh5/Makefile16
-rw-r--r--arch/sh/kernel/cpu/sh5/clock-sh5.c76
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S2000
-rw-r--r--arch/sh/kernel/cpu/sh5/fpu.c106
-rw-r--r--arch/sh/kernel/cpu/sh5/probe.c72
-rw-r--r--arch/sh/kernel/cpu/sh5/setup-sh5.c121
-rw-r--r--arch/sh/kernel/cpu/sh5/switchto.S195
-rw-r--r--arch/sh/kernel/cpu/sh5/unwind.c342
8 files changed, 0 insertions, 2928 deletions
diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile
deleted file mode 100644
index 97d23ec3005f..000000000000
--- a/arch/sh/kernel/cpu/sh5/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Linux/SuperH SH-5 backends.
-#
-obj-y := entry.o probe.o switchto.o
-
-obj-$(CONFIG_SH_FPU) += fpu.o
-obj-$(CONFIG_KALLSYMS) += unwind.o
-
-# CPU subtype setup
-obj-$(CONFIG_CPU_SH5) += setup-sh5.o
-
-# Primary on-chip clocks (common)
-clock-$(CONFIG_CPU_SH5) := clock-sh5.o
-
-obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c
deleted file mode 100644
index dee6be2c2344..000000000000
--- a/arch/sh/kernel/cpu/sh5/clock-sh5.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/sh/kernel/cpu/sh5/clock-sh5.c
- *
- * SH-5 support for the clock framework
- *
- * Copyright (C) 2008 Paul Mundt
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/clock.h>
-#include <asm/io.h>
-
-static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
-
-/* Clock, Power and Reset Controller */
-#define CPRC_BLOCK_OFF 0x01010000
-#define CPRC_BASE (PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF)
-
-static unsigned long cprc_base;
-
-static void master_clk_init(struct clk *clk)
-{
- int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
- clk->rate *= ifc_table[idx];
-}
-
-static struct sh_clk_ops sh5_master_clk_ops = {
- .init = master_clk_init,
-};
-
-static unsigned long module_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
- return clk->parent->rate / ifc_table[idx];
-}
-
-static struct sh_clk_ops sh5_module_clk_ops = {
- .recalc = module_clk_recalc,
-};
-
-static unsigned long bus_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
- return clk->parent->rate / ifc_table[idx];
-}
-
-static struct sh_clk_ops sh5_bus_clk_ops = {
- .recalc = bus_clk_recalc,
-};
-
-static unsigned long cpu_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readw(cprc_base) & 0x0007);
- return clk->parent->rate / ifc_table[idx];
-}
-
-static struct sh_clk_ops sh5_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
-};
-
-static struct sh_clk_ops *sh5_clk_ops[] = {
- &sh5_master_clk_ops,
- &sh5_module_clk_ops,
- &sh5_bus_clk_ops,
- &sh5_cpu_clk_ops,
-};
-
-void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
-{
- cprc_base = (unsigned long)ioremap(CPRC_BASE, 1024);
- BUG_ON(!cprc_base);
-
- if (idx < ARRAY_SIZE(sh5_clk_ops))
- *ops = sh5_clk_ops[idx];
-}
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
deleted file mode 100644
index 81c8b64b977f..000000000000
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ /dev/null
@@ -1,2000 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0
- *
- * arch/sh/kernel/cpu/sh5/entry.S
- *
- * Copyright (C) 2000, 2001 Paolo Alberelli
- * Copyright (C) 2004 - 2008 Paul Mundt
- * Copyright (C) 2003, 2004 Richard Curnow
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/sys.h>
-#include <cpu/registers.h>
-#include <asm/processor.h>
-#include <asm/unistd.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-
-/*
- * SR fields.
- */
-#define SR_ASID_MASK 0x00ff0000
-#define SR_FD_MASK 0x00008000
-#define SR_SS 0x08000000
-#define SR_BL 0x10000000
-#define SR_MD 0x40000000
-
-/*
- * Event code.
- */
-#define EVENT_INTERRUPT 0
-#define EVENT_FAULT_TLB 1
-#define EVENT_FAULT_NOT_TLB 2
-#define EVENT_DEBUG 3
-
-/* EXPEVT values */
-#define RESET_CAUSE 0x20
-#define DEBUGSS_CAUSE 0x980
-
-/*
- * Frame layout. Quad index.
- */
-#define FRAME_T(x) FRAME_TBASE+(x*8)
-#define FRAME_R(x) FRAME_RBASE+(x*8)
-#define FRAME_S(x) FRAME_SBASE+(x*8)
-#define FSPC 0
-#define FSSR 1
-#define FSYSCALL_ID 2
-
-/* Arrange the save frame to be a multiple of 32 bytes long */
-#define FRAME_SBASE 0
-#define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */
-#define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */
-#define FRAME_PBASE (FRAME_TBASE+(8*8)) /* tr0 -tr7 */
-#define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */
-
-#define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */
-#define FP_FRAME_BASE 0
-
-#define SAVED_R2 0*8
-#define SAVED_R3 1*8
-#define SAVED_R4 2*8
-#define SAVED_R5 3*8
-#define SAVED_R18 4*8
-#define SAVED_R6 5*8
-#define SAVED_TR0 6*8
-
-/* These are the registers saved in the TLB path that aren't saved in the first
- level of the normal one. */
-#define TLB_SAVED_R25 7*8
-#define TLB_SAVED_TR1 8*8
-#define TLB_SAVED_TR2 9*8
-#define TLB_SAVED_TR3 10*8
-#define TLB_SAVED_TR4 11*8
-/* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
- breakage otherwise. */
-#define TLB_SAVED_R0 12*8
-#define TLB_SAVED_R1 13*8
-
-#define CLI() \
- getcon SR, r6; \
- ori r6, 0xf0, r6; \
- putcon r6, SR;
-
-#define STI() \
- getcon SR, r6; \
- andi r6, ~0xf0, r6; \
- putcon r6, SR;
-
-#ifdef CONFIG_PREEMPTION
-# define preempt_stop() CLI()
-#else
-# define preempt_stop()
-# define resume_kernel restore_all
-#endif
-
- .section .data, "aw"
-
-#define FAST_TLBMISS_STACK_CACHELINES 4
-#define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
-
-/* Register back-up area for all exceptions */
- .balign 32
- /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
- * register saves etc. */
- .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
-/* This is 32 byte aligned by construction */
-/* Register back-up area for all exceptions */
-reg_save_area:
- .quad 0
- .quad 0
- .quad 0
- .quad 0
-
- .quad 0
- .quad 0
- .quad 0
- .quad 0
-
- .quad 0
- .quad 0
- .quad 0
- .quad 0
-
- .quad 0
- .quad 0
-
-/* Save area for RESVEC exceptions. We cannot use reg_save_area because of
- * reentrancy. Note this area may be accessed via physical address.
- * Align so this fits a whole single cache line, for ease of purging.
- */
- .balign 32,0,32
-resvec_save_area:
- .quad 0
- .quad 0
- .quad 0
- .quad 0
- .quad 0
- .balign 32,0,32
-
-/* Jump table of 3rd level handlers */
-trap_jtable:
- .long do_exception_error /* 0x000 */
- .long do_exception_error /* 0x020 */
-#ifdef CONFIG_MMU
- .long tlb_miss_load /* 0x040 */
- .long tlb_miss_store /* 0x060 */
-#else
- .long do_exception_error
- .long do_exception_error
-#endif
- ! ARTIFICIAL pseudo-EXPEVT setting
- .long do_debug_interrupt /* 0x080 */
-#ifdef CONFIG_MMU
- .long tlb_miss_load /* 0x0A0 */
- .long tlb_miss_store /* 0x0C0 */
-#else
- .long do_exception_error
- .long do_exception_error
-#endif
- .long do_address_error_load /* 0x0E0 */
- .long do_address_error_store /* 0x100 */
-#ifdef CONFIG_SH_FPU
- .long do_fpu_error /* 0x120 */
-#else
- .long do_exception_error /* 0x120 */
-#endif
- .long do_exception_error /* 0x140 */
- .long system_call /* 0x160 */
- .long do_reserved_inst /* 0x180 */
- .long do_illegal_slot_inst /* 0x1A0 */
- .long do_exception_error /* 0x1C0 - NMI */
- .long do_exception_error /* 0x1E0 */
- .rept 15
- .long do_IRQ /* 0x200 - 0x3C0 */
- .endr
- .long do_exception_error /* 0x3E0 */
- .rept 32
- .long do_IRQ /* 0x400 - 0x7E0 */
- .endr
- .long fpu_error_or_IRQA /* 0x800 */
- .long fpu_error_or_IRQB /* 0x820 */
- .long do_IRQ /* 0x840 */
- .long do_IRQ /* 0x860 */
- .rept 6
- .long do_exception_error /* 0x880 - 0x920 */
- .endr
- .long breakpoint_trap_handler /* 0x940 */
- .long do_exception_error /* 0x960 */
- .long do_single_step /* 0x980 */
-
- .rept 3
- .long do_exception_error /* 0x9A0 - 0x9E0 */
- .endr
- .long do_IRQ /* 0xA00 */
- .long do_IRQ /* 0xA20 */
-#ifdef CONFIG_MMU
- .long itlb_miss_or_IRQ /* 0xA40 */
-#else
- .long do_IRQ
-#endif
- .long do_IRQ /* 0xA60 */
- .long do_IRQ /* 0xA80 */
-#ifdef CONFIG_MMU
- .long itlb_miss_or_IRQ /* 0xAA0 */
-#else
- .long do_IRQ
-#endif
- .long do_exception_error /* 0xAC0 */
- .long do_address_error_exec /* 0xAE0 */
- .rept 8
- .long do_exception_error /* 0xB00 - 0xBE0 */
- .endr
- .rept 18
- .long do_IRQ /* 0xC00 - 0xE20 */
- .endr
-
- .section .text64, "ax"
-
-/*
- * --- Exception/Interrupt/Event Handling Section
- */
-
-/*
- * VBR and RESVEC blocks.
- *
- * First level handler for VBR-based exceptions.
- *
- * To avoid waste of space, align to the maximum text block size.
- * This is assumed to be at most 128 bytes or 32 instructions.
- * DO NOT EXCEED 32 instructions on the first level handlers !
- *
- * Also note that RESVEC is contained within the VBR block
- * where the room left (1KB - TEXT_SIZE) allows placing
- * the RESVEC block (at most 512B + TEXT_SIZE).
- *
- * So first (and only) level handler for RESVEC-based exceptions.
- *
- * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
- * and interrupt) we are a lot tight with register space until
- * saving onto the stack frame, which is done in handle_exception().
- *
- */
-
-#define TEXT_SIZE 128
-#define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */
-
- .balign TEXT_SIZE
-LVBR_block:
- .space 256, 0 /* Power-on class handler, */
- /* not required here */
-not_a_tlb_miss:
- synco /* TAKum03020 (but probably a good idea anyway.) */
- /* Save original stack pointer into KCR1 */
- putcon SP, KCR1
-
- /* Save other original registers into reg_save_area */
- movi reg_save_area, SP
- st.q SP, SAVED_R2, r2
- st.q SP, SAVED_R3, r3
- st.q SP, SAVED_R4, r4
- st.q SP, SAVED_R5, r5
- st.q SP, SAVED_R6, r6
- st.q SP, SAVED_R18, r18
- gettr tr0, r3
- st.q SP, SAVED_TR0, r3
-
- /* Set args for Non-debug, Not a TLB miss class handler */
- getcon EXPEVT, r2
- movi ret_from_exception, r3
- ori r3, 1, r3
- movi EVENT_FAULT_NOT_TLB, r4
- or SP, ZERO, r5
- getcon KCR1, SP
- pta handle_exception, tr0
- blink tr0, ZERO
-
- .balign 256
- ! VBR+0x200
- nop
- .balign 256
- ! VBR+0x300
- nop
- .balign 256
- /*
- * Instead of the natural .balign 1024 place RESVEC here
- * respecting the final 1KB alignment.
- */
- .balign TEXT_SIZE
- /*
- * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
- * block making sure the final alignment is correct.
- */
-#ifdef CONFIG_MMU
-tlb_miss:
- synco /* TAKum03020 (but probably a good idea anyway.) */
- putcon SP, KCR1
- movi reg_save_area, SP
- /* SP is guaranteed 32-byte aligned. */
- st.q SP, TLB_SAVED_R0 , r0
- st.q SP, TLB_SAVED_R1 , r1
- st.q SP, SAVED_R2 , r2
- st.q SP, SAVED_R3 , r3
- st.q SP, SAVED_R4 , r4
- st.q SP, SAVED_R5 , r5
- st.q SP, SAVED_R6 , r6
- st.q SP, SAVED_R18, r18
-
- /* Save R25 for safety; as/ld may want to use it to achieve the call to
- * the code in mm/tlbmiss.c */
- st.q SP, TLB_SAVED_R25, r25
- gettr tr0, r2
- gettr tr1, r3
- gettr tr2, r4
- gettr tr3, r5
- gettr tr4, r18
- st.q SP, SAVED_TR0 , r2
- st.q SP, TLB_SAVED_TR1 , r3
- st.q SP, TLB_SAVED_TR2 , r4
- st.q SP, TLB_SAVED_TR3 , r5
- st.q SP, TLB_SAVED_TR4 , r18
-
- pt do_fast_page_fault, tr0
- getcon SSR, r2
- getcon EXPEVT, r3
- getcon TEA, r4
- shlri r2, 30, r2
- andi r2, 1, r2 /* r2 = SSR.MD */
- blink tr0, LINK
-
- pt fixup_to_invoke_general_handler, tr1
-
- /* If the fast path handler fixed the fault, just drop through quickly
- to the restore code right away to return to the excepting context.
- */
- bnei/u r2, 0, tr1
-
-fast_tlb_miss_restore:
- ld.q SP, SAVED_TR0, r2
- ld.q SP, TLB_SAVED_TR1, r3
- ld.q SP, TLB_SAVED_TR2, r4
-
- ld.q SP, TLB_SAVED_TR3, r5
- ld.q SP, TLB_SAVED_TR4, r18
-
- ptabs r2, tr0
- ptabs r3, tr1
- ptabs r4, tr2
- ptabs r5, tr3
- ptabs r18, tr4
-
- ld.q SP, TLB_SAVED_R0, r0
- ld.q SP, TLB_SAVED_R1, r1
- ld.q SP, SAVED_R2, r2
- ld.q SP, SAVED_R3, r3
- ld.q SP, SAVED_R4, r4
- ld.q SP, SAVED_R5, r5
- ld.q SP, SAVED_R6, r6
- ld.q SP, SAVED_R18, r18
- ld.q SP, TLB_SAVED_R25, r25
-
- getcon KCR1, SP
- rte
- nop /* for safety, in case the code is run on sh5-101 cut1.x */
-
-fixup_to_invoke_general_handler:
-
- /* OK, new method. Restore stuff that's not expected to get saved into
- the 'first-level' reg save area, then just fall through to setting
- up the registers and calling the second-level handler. */
-
- /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore
- r25,tr1-4 and save r6 to get into the right state. */
-
- ld.q SP, TLB_SAVED_TR1, r3
- ld.q SP, TLB_SAVED_TR2, r4
- ld.q SP, TLB_SAVED_TR3, r5
- ld.q SP, TLB_SAVED_TR4, r18
- ld.q SP, TLB_SAVED_R25, r25
-
- ld.q SP, TLB_SAVED_R0, r0
- ld.q SP, TLB_SAVED_R1, r1
-
- ptabs/u r3, tr1
- ptabs/u r4, tr2
- ptabs/u r5, tr3
- ptabs/u r18, tr4
-
- /* Set args for Non-debug, TLB miss class handler */
- getcon EXPEVT, r2
- movi ret_from_exception, r3
- ori r3, 1, r3
- movi EVENT_FAULT_TLB, r4
- or SP, ZERO, r5
- getcon KCR1, SP
- pta handle_exception, tr0
- blink tr0, ZERO
-#else /* CONFIG_MMU */
- .balign 256
-#endif
-
-/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
- DOES END UP AT VBR+0x600 */
- nop
- nop
- nop
- nop
- nop
- nop
-
- .balign 256
- /* VBR + 0x600 */
-
-interrupt:
- synco /* TAKum03020 (but probably a good idea anyway.) */
- /* Save original stack pointer into KCR1 */
- putcon SP, KCR1
-
- /* Save other original registers into reg_save_area */
- movi reg_save_area, SP
- st.q SP, SAVED_R2, r2
- st.q SP, SAVED_R3, r3
- st.q SP, SAVED_R4, r4
- st.q SP, SAVED_R5, r5
- st.q SP, SAVED_R6, r6
- st.q SP, SAVED_R18, r18
- gettr tr0, r3
- st.q SP, SAVED_TR0, r3
-
- /* Set args for interrupt class handler */
- getcon INTEVT, r2
- movi ret_from_irq, r3
- ori r3, 1, r3
- movi EVENT_INTERRUPT, r4
- or SP, ZERO, r5
- getcon KCR1, SP
- pta handle_exception, tr0
- blink tr0, ZERO
- .balign TEXT_SIZE /* let's waste the bare minimum */
-
-LVBR_block_end: /* Marker. Used for total checking */
-
- .balign 256
-LRESVEC_block:
- /* Panic handler. Called with MMU off. Possible causes/actions:
- * - Reset: Jump to program start.
- * - Single Step: Turn off Single Step & return.
- * - Others: Call panic handler, passing PC as arg.
- * (this may need to be extended...)
- */
-reset_or_panic:
- synco /* TAKum03020 (but probably a good idea anyway.) */
- putcon SP, DCR
- /* First save r0-1 and tr0, as we need to use these */
- movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
- st.q SP, 0, r0
- st.q SP, 8, r1
- gettr tr0, r0
- st.q SP, 32, r0
-
- /* Check cause */
- getcon EXPEVT, r0
- movi RESET_CAUSE, r1
- sub r1, r0, r1 /* r1=0 if reset */
- movi _stext-CONFIG_PAGE_OFFSET, r0
- ori r0, 1, r0
- ptabs r0, tr0
- beqi r1, 0, tr0 /* Jump to start address if reset */
-
- getcon EXPEVT, r0
- movi DEBUGSS_CAUSE, r1
- sub r1, r0, r1 /* r1=0 if single step */
- pta single_step_panic, tr0
- beqi r1, 0, tr0 /* jump if single step */
-
- /* Now jump to where we save the registers. */
- movi panic_stash_regs-CONFIG_PAGE_OFFSET, r1
- ptabs r1, tr0
- blink tr0, r63
-
-single_step_panic:
- /* We are in a handler with Single Step set. We need to resume the
- * handler, by turning on MMU & turning off Single Step. */
- getcon SSR, r0
- movi SR_MMU, r1
- or r0, r1, r0
- movi ~SR_SS, r1
- and r0, r1, r0
- putcon r0, SSR
- /* Restore EXPEVT, as the rte won't do this */
- getcon PEXPEVT, r0
- putcon r0, EXPEVT
- /* Restore regs */
- ld.q SP, 32, r0
- ptabs r0, tr0
- ld.q SP, 0, r0
- ld.q SP, 8, r1
- getcon DCR, SP
- synco
- rte
-
-
- .balign 256
-debug_exception:
- synco /* TAKum03020 (but probably a good idea anyway.) */
- /*
- * Single step/software_break_point first level handler.
- * Called with MMU off, so the first thing we do is enable it
- * by doing an rte with appropriate SSR.
- */
- putcon SP, DCR
- /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
- movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
-
- /* With the MMU off, we are bypassing the cache, so purge any
- * data that will be made stale by the following stores.
- */
- ocbp SP, 0
- synco
-
- st.q SP, 0, r0
- st.q SP, 8, r1
- getcon SPC, r0
- st.q SP, 16, r0
- getcon SSR, r0
- st.q SP, 24, r0
-
- /* Enable MMU, block exceptions, set priv mode, disable single step */
- movi SR_MMU | SR_BL | SR_MD, r1
- or r0, r1, r0
- movi ~SR_SS, r1
- and r0, r1, r0
- putcon r0, SSR
- /* Force control to debug_exception_2 when rte is executed */
- movi debug_exeception_2, r0
- ori r0, 1, r0 /* force SHmedia, just in case */
- putcon r0, SPC
- getcon DCR, SP
- synco
- rte
-debug_exeception_2:
- /* Restore saved regs */
- putcon SP, KCR1
- movi resvec_save_area, SP
- ld.q SP, 24, r0
- putcon r0, SSR
- ld.q SP, 16, r0
- putcon r0, SPC
- ld.q SP, 0, r0
- ld.q SP, 8, r1
-
- /* Save other original registers into reg_save_area */
- movi reg_save_area, SP
- st.q SP, SAVED_R2, r2
- st.q SP, SAVED_R3, r3
- st.q SP, SAVED_R4, r4
- st.q SP, SAVED_R5, r5
- st.q SP, SAVED_R6, r6
- st.q SP, SAVED_R18, r18
- gettr tr0, r3
- st.q SP, SAVED_TR0, r3
-
- /* Set args for debug class handler */
- getcon EXPEVT, r2
- movi ret_from_exception, r3
- ori r3, 1, r3
- movi EVENT_DEBUG, r4
- or SP, ZERO, r5
- getcon KCR1, SP
- pta handle_exception, tr0
- blink tr0, ZERO
-
- .balign 256
-debug_interrupt:
- /* !!! WE COME HERE IN REAL MODE !!! */
- /* Hook-up debug interrupt to allow various debugging options to be
- * hooked into its handler. */
- /* Save original stack pointer into KCR1 */
- synco
- putcon SP, KCR1
- movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
- ocbp SP, 0
- ocbp SP, 32
- synco
-
- /* Save other original registers into reg_save_area thru real addresses */
- st.q SP, SAVED_R2, r2
- st.q SP, SAVED_R3, r3
- st.q SP, SAVED_R4, r4
- st.q SP, SAVED_R5, r5
- st.q SP, SAVED_R6, r6
- st.q SP, SAVED_R18, r18
- gettr tr0, r3
- st.q SP, SAVED_TR0, r3
-
- /* move (spc,ssr)->(pspc,pssr). The rte will shift
- them back again, so that they look like the originals
- as far as the real handler code is concerned. */
- getcon spc, r6
- putcon r6, pspc
- getcon ssr, r6
- putcon r6, pssr
-
- ! construct useful SR for handle_exception
- movi 3, r6
- shlli r6, 30, r6
- getcon sr, r18
- or r18, r6, r6
- putcon r6, ssr
-
- ! SSR is now the current SR with the MD and MMU bits set
- ! i.e. the rte will switch back to priv mode and put
- ! the mmu back on
-
- ! construct spc
- movi handle_exception, r18
- ori r18, 1, r18 ! for safety (do we need this?)
- putcon r18, spc
-
- /* Set args for Non-debug, Not a TLB miss class handler */
-
- ! EXPEVT==0x80 is unused, so 'steal' this value to put the
- ! debug interrupt handler in the vectoring table
- movi 0x80, r2
- movi ret_from_exception, r3
- ori r3, 1, r3
- movi EVENT_FAULT_NOT_TLB, r4
-
- or SP, ZERO, r5
- movi CONFIG_PAGE_OFFSET, r6
- add r6, r5, r5
- getcon KCR1, SP
-
- synco ! for safety
- rte ! -> handle_exception, switch back to priv mode again
-
-LRESVEC_block_end: /* Marker. Unused. */
-
- .balign TEXT_SIZE
-
-/*
- * Second level handler for VBR-based exceptions. Pre-handler.
- * In common to all stack-frame sensitive handlers.
- *
- * Inputs:
- * (KCR0) Current [current task union]
- * (KCR1) Original SP
- * (r2) INTEVT/EXPEVT
- * (r3) appropriate return address
- * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
- * (r5) Pointer to reg_save_area
- * (SP) Original SP
- *
- * Available registers:
- * (r6)
- * (r18)
- * (tr0)
- *
- */
-handle_exception:
- /* Common 2nd level handler. */
-
- /* First thing we need an appropriate stack pointer */
- getcon SSR, r6
- shlri r6, 30, r6
- andi r6, 1, r6
- pta stack_ok, tr0
- bne r6, ZERO, tr0 /* Original stack pointer is fine */
-
- /* Set stack pointer for user fault */
- getcon KCR0, SP
- movi THREAD_SIZE, r6 /* Point to the end */
- add SP, r6, SP
-
-stack_ok:
-
-/* DEBUG : check for underflow/overflow of the kernel stack */
- pta no_underflow, tr0
- getcon KCR0, r6
- movi 1024, r18
- add r6, r18, r6
- bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone
-
-/* Just panic to cause a crash. */
-bad_sp:
- ld.b r63, 0, r6
- nop
-
-no_underflow:
- pta bad_sp, tr0
- getcon kcr0, r6
- movi THREAD_SIZE, r18
- add r18, r6, r6
- bgt SP, r6, tr0 ! sp above the stack
-
- /* Make some room for the BASIC frame. */
- movi -(FRAME_SIZE), r6
- add SP, r6, SP
-
-/* Could do this with no stalling if we had another spare register, but the
- code below will be OK. */
- ld.q r5, SAVED_R2, r6
- ld.q r5, SAVED_R3, r18
- st.q SP, FRAME_R(2), r6
- ld.q r5, SAVED_R4, r6
- st.q SP, FRAME_R(3), r18
- ld.q r5, SAVED_R5, r18
- st.q SP, FRAME_R(4), r6
- ld.q r5, SAVED_R6, r6
- st.q SP, FRAME_R(5), r18
- ld.q r5, SAVED_R18, r18
- st.q SP, FRAME_R(6), r6
- ld.q r5, SAVED_TR0, r6
- st.q SP, FRAME_R(18), r18
- st.q SP, FRAME_T(0), r6
-
- /* Keep old SP around */
- getcon KCR1, r6
-
- /* Save the rest of the general purpose registers */
- st.q SP, FRAME_R(0), r0
- st.q SP, FRAME_R(1), r1
- st.q SP, FRAME_R(7), r7
- st.q SP, FRAME_R(8), r8
- st.q SP, FRAME_R(9), r9
- st.q SP, FRAME_R(10), r10
- st.q SP, FRAME_R(11), r11
- st.q SP, FRAME_R(12), r12
- st.q SP, FRAME_R(13), r13
- st.q SP, FRAME_R(14), r14
-
- /* SP is somewhere else */
- st.q SP, FRAME_R(15), r6
-
- st.q SP, FRAME_R(16), r16
- st.q SP, FRAME_R(17), r17
- /* r18 is saved earlier. */
- st.q SP, FRAME_R(19), r19
- st.q SP, FRAME_R(20), r20
- st.q SP, FRAME_R(21), r21
- st.q SP, FRAME_R(22), r22
- st.q SP, FRAME_R(23), r23
- st.q SP, FRAME_R(24), r24
- st.q SP, FRAME_R(25), r25
- st.q SP, FRAME_R(26), r26
- st.q SP, FRAME_R(27), r27
- st.q SP, FRAME_R(28), r28
- st.q SP, FRAME_R(29), r29
- st.q SP, FRAME_R(30), r30
- st.q SP, FRAME_R(31), r31
- st.q SP, FRAME_R(32), r32
- st.q SP, FRAME_R(33), r33
- st.q SP, FRAME_R(34), r34
- st.q SP, FRAME_R(35), r35
- st.q SP, FRAME_R(36), r36
- st.q SP, FRAME_R(37), r37
- st.q SP, FRAME_R(38), r38
- st.q SP, FRAME_R(39), r39
- st.q SP, FRAME_R(40), r40
- st.q SP, FRAME_R(41), r41
- st.q SP, FRAME_R(42), r42
- st.q SP, FRAME_R(43), r43
- st.q SP, FRAME_R(44), r44
- st.q SP, FRAME_R(45), r45
- st.q SP, FRAME_R(46), r46
- st.q SP, FRAME_R(47), r47
- st.q SP, FRAME_R(48), r48
- st.q SP, FRAME_R(49), r49
- st.q SP, FRAME_R(50), r50
- st.q SP, FRAME_R(51), r51
- st.q SP, FRAME_R(52), r52
- st.q SP, FRAME_R(53), r53
- st.q SP, FRAME_R(54), r54
- st.q SP, FRAME_R(55), r55
- st.q SP, FRAME_R(56), r56
- st.q SP, FRAME_R(57), r57
- st.q SP, FRAME_R(58), r58
- st.q SP, FRAME_R(59), r59
- st.q SP, FRAME_R(60), r60
- st.q SP, FRAME_R(61), r61
- st.q SP, FRAME_R(62), r62
-
- /*
- * Save the S* registers.
- */
- getcon SSR, r61
- st.q SP, FRAME_S(FSSR), r61
- getcon SPC, r62
- st.q SP, FRAME_S(FSPC), r62
- movi -1, r62 /* Reset syscall_nr */
- st.q SP, FRAME_S(FSYSCALL_ID), r62
-
- /* Save the rest of the target registers */
- gettr tr1, r6
- st.q SP, FRAME_T(1), r6
- gettr tr2, r6
- st.q SP, FRAME_T(2), r6
- gettr tr3, r6
- st.q SP, FRAME_T(3), r6
- gettr tr4, r6
- st.q SP, FRAME_T(4), r6
- gettr tr5, r6
- st.q SP, FRAME_T(5), r6
- gettr tr6, r6
- st.q SP, FRAME_T(6), r6
- gettr tr7, r6
- st.q SP, FRAME_T(7), r6
-
- ! setup FP so that unwinder can wind back through nested kernel mode
- ! exceptions
- add SP, ZERO, r14
-
- /* For syscall and debug race condition, get TRA now */
- getcon TRA, r5
-
- /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
- * Also set FD, to catch FPU usage in the kernel.
- *
- * benedict.gaster@superh.com 29/07/2002
- *
- * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
- * same time change BL from 1->0, as any pending interrupt of a level
- * higher than he previous value of IMASK will leak through and be
- * taken unexpectedly.
- *
- * To avoid this we raise the IMASK and then issue another PUTCON to
- * enable interrupts.
- */
- getcon SR, r6
- movi SR_IMASK | SR_FD, r7
- or r6, r7, r6
- putcon r6, SR
- movi SR_UNBLOCK_EXC, r7
- and r6, r7, r6
- putcon r6, SR
-
-
- /* Now call the appropriate 3rd level handler */
- or r3, ZERO, LINK
- movi trap_jtable, r3
- shlri r2, 3, r2
- ldx.l r2, r3, r3
- shlri r2, 2, r2
- ptabs r3, tr0
- or SP, ZERO, r3
- blink tr0, ZERO
-
-/*
- * Second level handler for VBR-based exceptions. Post-handlers.
- *
- * Post-handlers for interrupts (ret_from_irq), exceptions
- * (ret_from_exception) and common reentrance doors (restore_all
- * to get back to the original context, ret_from_syscall loop to
- * check kernel exiting).
- *
- * ret_with_reschedule and work_notifysig are an inner lables of
- * the ret_from_syscall loop.
- *
- * In common to all stack-frame sensitive handlers.
- *
- * Inputs:
- * (SP) struct pt_regs *, original register's frame pointer (basic)
- *
- */
- .global ret_from_irq
-ret_from_irq:
- ld.q SP, FRAME_S(FSSR), r6
- shlri r6, 30, r6
- andi r6, 1, r6
- pta resume_kernel, tr0
- bne r6, ZERO, tr0 /* no further checks */
- STI()
- pta ret_with_reschedule, tr0
- blink tr0, ZERO /* Do not check softirqs */
-
- .global ret_from_exception
-ret_from_exception:
- preempt_stop()
-
- ld.q SP, FRAME_S(FSSR), r6
- shlri r6, 30, r6
- andi r6, 1, r6
- pta resume_kernel, tr0
- bne r6, ZERO, tr0 /* no further checks */
-
- /* Check softirqs */
-
-#ifdef CONFIG_PREEMPTION
- pta ret_from_syscall, tr0
- blink tr0, ZERO
-
-resume_kernel:
- CLI()
-
- pta restore_all, tr0
-
- getcon KCR0, r6
- ld.l r6, TI_PRE_COUNT, r7
- beq/u r7, ZERO, tr0
-
-need_resched:
- ld.l r6, TI_FLAGS, r7
- movi (1 << TIF_NEED_RESCHED), r8
- and r8, r7, r8
- bne r8, ZERO, tr0
-
- getcon SR, r7
- andi r7, 0xf0, r7
- bne r7, ZERO, tr0
-
- movi preempt_schedule_irq, r7
- ori r7, 1, r7
- ptabs r7, tr1
- blink tr1, LINK
-
- pta need_resched, tr1
- blink tr1, ZERO
-#endif
-
- .global ret_from_syscall
-ret_from_syscall:
-
-ret_with_reschedule:
- getcon KCR0, r6 ! r6 contains current_thread_info
- ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
-
- movi _TIF_NEED_RESCHED, r8
- and r8, r7, r8
- pta work_resched, tr0
- bne r8, ZERO, tr0
-
- pta restore_all, tr1
-
- movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
- and r8, r7, r8
- pta work_notifysig, tr0
- bne r8, ZERO, tr0
-
- blink tr1, ZERO
-
-work_resched:
- pta ret_from_syscall, tr0
- gettr tr0, LINK
- movi schedule, r6
- ptabs r6, tr0
- blink tr0, ZERO /* Call schedule(), return on top */
-
-work_notifysig:
- gettr tr1, LINK
-
- movi do_notify_resume, r6
- ptabs r6, tr0
- or SP, ZERO, r2
- or r7, ZERO, r3
- blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
-
-restore_all:
- /* Do prefetches */
-
- ld.q SP, FRAME_T(0), r6
- ld.q SP, FRAME_T(1), r7
- ld.q SP, FRAME_T(2), r8
- ld.q SP, FRAME_T(3), r9
- ptabs r6, tr0
- ptabs r7, tr1
- ptabs r8, tr2
- ptabs r9, tr3
- ld.q SP, FRAME_T(4), r6
- ld.q SP, FRAME_T(5), r7
- ld.q SP, FRAME_T(6), r8
- ld.q SP, FRAME_T(7), r9
- ptabs r6, tr4
- ptabs r7, tr5
- ptabs r8, tr6
- ptabs r9, tr7
-
- ld.q SP, FRAME_R(0), r0
- ld.q SP, FRAME_R(1), r1
- ld.q SP, FRAME_R(2), r2
- ld.q SP, FRAME_R(3), r3
- ld.q SP, FRAME_R(4), r4
- ld.q SP, FRAME_R(5), r5
- ld.q SP, FRAME_R(6), r6
- ld.q SP, FRAME_R(7), r7
- ld.q SP, FRAME_R(8), r8
- ld.q SP, FRAME_R(9), r9
- ld.q SP, FRAME_R(10), r10
- ld.q SP, FRAME_R(11), r11
- ld.q SP, FRAME_R(12), r12
- ld.q SP, FRAME_R(13), r13
- ld.q SP, FRAME_R(14), r14
-
- ld.q SP, FRAME_R(16), r16
- ld.q SP, FRAME_R(17), r17
- ld.q SP, FRAME_R(18), r18
- ld.q SP, FRAME_R(19), r19
- ld.q SP, FRAME_R(20), r20
- ld.q SP, FRAME_R(21), r21
- ld.q SP, FRAME_R(22), r22
- ld.q SP, FRAME_R(23), r23
- ld.q SP, FRAME_R(24), r24
- ld.q SP, FRAME_R(25), r25
- ld.q SP, FRAME_R(26), r26
- ld.q SP, FRAME_R(27), r27
- ld.q SP, FRAME_R(28), r28
- ld.q SP, FRAME_R(29), r29
- ld.q SP, FRAME_R(30), r30
- ld.q SP, FRAME_R(31), r31
- ld.q SP, FRAME_R(32), r32
- ld.q SP, FRAME_R(33), r33
- ld.q SP, FRAME_R(34), r34
- ld.q SP, FRAME_R(35), r35
- ld.q SP, FRAME_R(36), r36
- ld.q SP, FRAME_R(37), r37
- ld.q SP, FRAME_R(38), r38
- ld.q SP, FRAME_R(39), r39
- ld.q SP, FRAME_R(40), r40
- ld.q SP, FRAME_R(41), r41
- ld.q SP, FRAME_R(42), r42
- ld.q SP, FRAME_R(43), r43
- ld.q SP, FRAME_R(44), r44
- ld.q SP, FRAME_R(45), r45
- ld.q SP, FRAME_R(46), r46
- ld.q SP, FRAME_R(47), r47
- ld.q SP, FRAME_R(48), r48
- ld.q SP, FRAME_R(49), r49
- ld.q SP, FRAME_R(50), r50
- ld.q SP, FRAME_R(51), r51
- ld.q SP, FRAME_R(52), r52
- ld.q SP, FRAME_R(53), r53
- ld.q SP, FRAME_R(54), r54
- ld.q SP, FRAME_R(55), r55
- ld.q SP, FRAME_R(56), r56
- ld.q SP, FRAME_R(57), r57
- ld.q SP, FRAME_R(58), r58
-
- getcon SR, r59
- movi SR_BLOCK_EXC, r60
- or r59, r60, r59
- putcon r59, SR /* SR.BL = 1, keep nesting out */
- ld.q SP, FRAME_S(FSSR), r61
- ld.q SP, FRAME_S(FSPC), r62
- movi SR_ASID_MASK, r60
- and r59, r60, r59
- andc r61, r60, r61 /* Clear out older ASID */
- or r59, r61, r61 /* Retain current ASID */
- putcon r61, SSR
- putcon r62, SPC
-
- /* Ignore FSYSCALL_ID */
-
- ld.q SP, FRAME_R(59), r59
- ld.q SP, FRAME_R(60), r60
- ld.q SP, FRAME_R(61), r61
- ld.q SP, FRAME_R(62), r62
-
- /* Last touch */
- ld.q SP, FRAME_R(15), SP
- rte
- nop
-
-/*
- * Third level handlers for VBR-based exceptions. Adapting args to
- * and/or deflecting to fourth level handlers.
- *
- * Fourth level handlers interface.
- * Most are C-coded handlers directly pointed by the trap_jtable.
- * (Third = Fourth level)
- * Inputs:
- * (r2) fault/interrupt code, entry number (e.g. NMI = 14,
- * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
- * (r3) struct pt_regs *, original register's frame pointer
- * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
- * (r5) TRA control register (for syscall/debug benefit only)
- * (LINK) return address
- * (SP) = r3
- *
- * Kernel TLB fault handlers will get a slightly different interface.
- * (r2) struct pt_regs *, original register's frame pointer
- * (r3) page fault error code (see asm/thread_info.h)
- * (r4) Effective Address of fault
- * (LINK) return address
- * (SP) = r2
- *
- * fpu_error_or_IRQ? is a helper to deflect to the right cause.
- *
- */
-#ifdef CONFIG_MMU
-tlb_miss_load:
- or SP, ZERO, r2
- or ZERO, ZERO, r3 /* Read */
- getcon TEA, r4
- pta call_do_page_fault, tr0
- beq ZERO, ZERO, tr0
-
-tlb_miss_store:
- or SP, ZERO, r2
- movi FAULT_CODE_WRITE, r3 /* Write */
- getcon TEA, r4
- pta call_do_page_fault, tr0
- beq ZERO, ZERO, tr0
-
-itlb_miss_or_IRQ:
- pta its_IRQ, tr0
- beqi/u r4, EVENT_INTERRUPT, tr0
-
- /*