aboutsummaryrefslogtreecommitdiffstats
path: root/arch/metag
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2013-11-05 09:42:03 -0500
committerJames Hogan <james.hogan@imgtec.com>2013-11-06 05:40:02 -0500
commit95281171a713f4d32f1a044b937563ec7776ccfe (patch)
tree3071f6b6caa68a38348b4996dc873f2b0aa3014a /arch/metag
parent5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff)
metag: handle low level kicks directly
Kick interrupts trigger the LWK (low level kick) signal, usually handled by the __TBIDoStdLWK() function which is the only handler inherited from the bootloader. The LWK signal is converted either to a SWK (plain software kick) or a SWS (software kick with an attached message). Linux has kick_handler() to handle SWK and call registered kick handlers (IPIs and inter-thread comms), but SWS is as far as I'm aware unused with Linux. Therefore remove that abstraction and have Linux handle LWK directly. This will reduce kick latency slightly, and reduce our dependence on the bootloader, which makes it easier to directly boot a kernel in QEMU (particularly for SMP). Signed-off-by: James Hogan <james.hogan@imgtec.com>
Diffstat (limited to 'arch/metag')
-rw-r--r--arch/metag/include/asm/tbx.h19
-rw-r--r--arch/metag/kernel/setup.c6
-rw-r--r--arch/metag/kernel/traps.c5
-rw-r--r--arch/metag/tbx/tbidefr.S2
4 files changed, 11 insertions, 21 deletions
diff --git a/arch/metag/include/asm/tbx.h b/arch/metag/include/asm/tbx.h
index 287b36ff8ad1..703b9cb0ac5c 100644
--- a/arch/metag/include/asm/tbx.h
+++ b/arch/metag/include/asm/tbx.h
@@ -150,11 +150,9 @@
150#else 150#else
151/* Reserved 0x04-0x09 */ 151/* Reserved 0x04-0x09 */
152#endif 152#endif
153#define TBID_SIGNUM_SWS 0x0A /* KICK received with SigMask != 0 */ 153/* Reserved 0x0A-0x0F */
154#define TBID_SIGNUM_SWK 0x0B /* KICK received with SigMask == 0 */
155/* Reserved 0x0C-0x0F */
156#define TBID_SIGNUM_TRT 0x10 /* Timer trigger */ 154#define TBID_SIGNUM_TRT 0x10 /* Timer trigger */
157#define TBID_SIGNUM_LWK 0x11 /* Low level kick (handler provided by TBI) */ 155#define TBID_SIGNUM_LWK 0x11 /* Low level kick */
158#define TBID_SIGNUM_XXF 0x12 /* Fault handler - receives ALL _xxF sigs */ 156#define TBID_SIGNUM_XXF 0x12 /* Fault handler - receives ALL _xxF sigs */
159#ifdef TBI_1_4 157#ifdef TBI_1_4
160#define TBID_SIGNUM_DFR 0x13 /* Deferred Exception handler */ 158#define TBID_SIGNUM_DFR 0x13 /* Deferred Exception handler */
@@ -183,8 +181,7 @@
183 each hardware signal, sometimes this is a many-to-one relationship. */ 181 each hardware signal, sometimes this is a many-to-one relationship. */
184#define TBI_TRIG_BIT(SigNum) (\ 182#define TBI_TRIG_BIT(SigNum) (\
185 ((SigNum) >= TBID_SIGNUM_TRT) ? 1<<((SigNum)-TBID_SIGNUM_TRT) :\ 183 ((SigNum) >= TBID_SIGNUM_TRT) ? 1<<((SigNum)-TBID_SIGNUM_TRT) :\
186 ( ((SigNum) == TBID_SIGNUM_SWS) || \ 184 ((SigNum) == TBID_SIGNUM_LWK) ? \
187 ((SigNum) == TBID_SIGNUM_SWK) ) ? \
188 TXSTAT_KICK_BIT : TXSTATI_BGNDHALT_BIT ) 185 TXSTAT_KICK_BIT : TXSTATI_BGNDHALT_BIT )
189 186
190/* Return the hardware trigger vector number for entries in the 187/* Return the hardware trigger vector number for entries in the
@@ -687,10 +684,8 @@ typedef union _tbires_tag_ {
687 Triggers will indicate the status of TXSTAT or TXSTATI sampled by the 684 Triggers will indicate the status of TXSTAT or TXSTATI sampled by the
688 code that called the handler. 685 code that called the handler.
689 686
690 InstOrSWSId is defined firstly as 'Inst' if the SigNum is TBID_SIGNUM_SWx 687 Inst is defined as 'Inst' if the SigNum is TBID_SIGNUM_SWx and holds the
691 and hold the actual SWITCH instruction detected, secondly if SigNum 688 actual SWITCH instruction detected, in other cases the value of this
692 is TBID_SIGNUM_SWS the 'SWSId' is defined to hold the Id of the
693 software signal detected, in other cases the value of this
694 parameter is undefined. 689 parameter is undefined.
695 690
696 pTBI points at the PTBI structure related to the thread and processing 691 pTBI points at the PTBI structure related to the thread and processing
@@ -709,7 +704,7 @@ typedef union _tbires_tag_ {
709 704
710 */ 705 */
711typedef TBIRES (*PTBIAPIFN)( TBIRES State, int SigNum, 706typedef TBIRES (*PTBIAPIFN)( TBIRES State, int SigNum,
712 int Triggers, int InstOrSWSId, 707 int Triggers, int Inst,
713 volatile struct _tbi_tag_ *pTBI ); 708 volatile struct _tbi_tag_ *pTBI );
714#endif /* ifndef __ASSEMBLY__ */ 709#endif /* ifndef __ASSEMBLY__ */
715 710
@@ -757,7 +752,7 @@ typedef volatile struct _tbi_tag_ {
757#ifndef __ASSEMBLY__ 752#ifndef __ASSEMBLY__
758/* This handler should be used for TBID_SIGNUM_DFR */ 753/* This handler should be used for TBID_SIGNUM_DFR */
759extern TBIRES __TBIHandleDFR ( TBIRES State, int SigNum, 754extern TBIRES __TBIHandleDFR ( TBIRES State, int SigNum,
760 int Triggers, int InstOrSWSId, 755 int Triggers, int Inst,
761 volatile struct _tbi_tag_ *pTBI ); 756 volatile struct _tbi_tag_ *pTBI );
762#endif 757#endif
763#endif 758#endif
diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c
index c396cd0b425f..e639bae09645 100644
--- a/arch/metag/kernel/setup.c
+++ b/arch/metag/kernel/setup.c
@@ -302,13 +302,9 @@ void __init setup_arch(char **cmdline_p)
302 * rather than the version from the bootloader. This makes call 302 * rather than the version from the bootloader. This makes call
303 * stacks easier to understand and may allow us to unmap the 303 * stacks easier to understand and may allow us to unmap the
304 * bootloader at some point. 304 * bootloader at some point.
305 *
306 * We need to keep the LWK handler that TBI installed in order to
307 * be able to do inter-thread comms.
308 */ 305 */
309 for (i = 0; i <= TBID_SIGNUM_MAX; i++) 306 for (i = 0; i <= TBID_SIGNUM_MAX; i++)
310 if (i != TBID_SIGNUM_LWK) 307 _pTBI->fnSigs[i] = __TBIUnExpXXX;
311 _pTBI->fnSigs[i] = __TBIUnExpXXX;
312 308
313 /* A Meta requirement is that the kernel is loaded (virtually) 309 /* A Meta requirement is that the kernel is loaded (virtually)
314 * at the PAGE_OFFSET. 310 * at the PAGE_OFFSET.
diff --git a/arch/metag/kernel/traps.c b/arch/metag/kernel/traps.c
index 25f9d1c2ffec..17b2e2e38d5a 100644
--- a/arch/metag/kernel/traps.c
+++ b/arch/metag/kernel/traps.c
@@ -819,8 +819,7 @@ void per_cpu_trap_init(unsigned long cpu)
819 819
820 set_trigger_mask(TBI_INTS_INIT(thread) | /* interrupts */ 820 set_trigger_mask(TBI_INTS_INIT(thread) | /* interrupts */
821 TBI_TRIG_BIT(TBID_SIGNUM_LWK) | /* low level kick */ 821 TBI_TRIG_BIT(TBID_SIGNUM_LWK) | /* low level kick */
822 TBI_TRIG_BIT(TBID_SIGNUM_SW1) | 822 TBI_TRIG_BIT(TBID_SIGNUM_SW1));
823 TBI_TRIG_BIT(TBID_SIGNUM_SWS));
824 823
825 /* non-priv - use current stack */ 824 /* non-priv - use current stack */
826 int_context.Sig.pCtx = NULL; 825 int_context.Sig.pCtx = NULL;
@@ -842,7 +841,7 @@ void __init trap_init(void)
842 _pTBI->fnSigs[TBID_SIGNUM_SW1] = switch1_handler; 841 _pTBI->fnSigs[TBID_SIGNUM_SW1] = switch1_handler;
843 _pTBI->fnSigs[TBID_SIGNUM_SW2] = switchx_handler; 842 _pTBI->fnSigs[TBID_SIGNUM_SW2] = switchx_handler;
844 _pTBI->fnSigs[TBID_SIGNUM_SW3] = switchx_handler; 843 _pTBI->fnSigs[TBID_SIGNUM_SW3] = switchx_handler;
845 _pTBI->fnSigs[TBID_SIGNUM_SWK] = kick_handler; 844 _pTBI->fnSigs[TBID_SIGNUM_LWK] = kick_handler;
846 845
847#ifdef CONFIG_METAG_META21 846#ifdef CONFIG_METAG_META21
848 _pTBI->fnSigs[TBID_SIGNUM_DFR] = __TBIHandleDFR; 847 _pTBI->fnSigs[TBID_SIGNUM_DFR] = __TBIHandleDFR;
diff --git a/arch/metag/tbx/tbidefr.S b/arch/metag/tbx/tbidefr.S
index 3eb165ebf540..8f0902b22f70 100644
--- a/arch/metag/tbx/tbidefr.S
+++ b/arch/metag/tbx/tbidefr.S
@@ -20,7 +20,7 @@
20/* D1Ar1:D0Ar2 -- State 20/* D1Ar1:D0Ar2 -- State
21 * D0Ar3 -- SigNum 21 * D0Ar3 -- SigNum
22 * D0Ar4 -- Triggers 22 * D0Ar4 -- Triggers
23 * D1Ar5 -- InstOrSWSId 23 * D1Ar5 -- Inst
24 * D0Ar6 -- pTBI (volatile) 24 * D0Ar6 -- pTBI (volatile)
25 */ 25 */
26___TBIHandleDFR: 26___TBIHandleDFR: