diff options
author | James Hogan <james.hogan@imgtec.com> | 2012-09-21 17:40:06 +0100 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2013-03-02 20:09:18 +0000 |
commit | 027f891f7640144d4b7b15113f3ae9af2c8b095d (patch) | |
tree | cee318450f4782ca3a471f83ef3fd3557e8c3a9d /arch/metag/tbx/tbidefr.S | |
parent | 4ca151b20803eb2e31bb6d840d01eec461158e14 (diff) |
metag: TBX source
Add source files from the Thread Binary Interface (TBI) library which
provides useful low level operations and traps/context management.
Among other things it handles interrupt/exception/syscall entry (in
tbipcx.S).
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Diffstat (limited to 'arch/metag/tbx/tbidefr.S')
-rw-r--r-- | arch/metag/tbx/tbidefr.S | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/arch/metag/tbx/tbidefr.S b/arch/metag/tbx/tbidefr.S new file mode 100644 index 000000000000..3eb165ebf540 --- /dev/null +++ b/arch/metag/tbx/tbidefr.S @@ -0,0 +1,175 @@ +/* + * tbidefr.S + * + * Copyright (C) 2009, 2012 Imagination Technologies. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * Routing deferred exceptions + */ + +#include <asm/metag_regs.h> +#include <asm/tbx.h> + + .text + .balign 4 + .global ___TBIHandleDFR + .type ___TBIHandleDFR,function +/* D1Ar1:D0Ar2 -- State + * D0Ar3 -- SigNum + * D0Ar4 -- Triggers + * D1Ar5 -- InstOrSWSId + * D0Ar6 -- pTBI (volatile) + */ +___TBIHandleDFR: +#ifdef META_BUG_MBN100212 + MSETL [A0StP++], D0FrT, D0.5 + + /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved + * D0Ar4 -- The deferred exceptions + * D1Ar3 -- As per D0Ar4 but just the trigger bits + * D0.5 -- The bgnd deferred exceptions + * D1.5 -- TXDEFR with bgnd re-added + */ + + /* - Collect the pending deferred exceptions using TXSTAT, + * (ack's the bgnd exceptions as a side-effect) + * - Manually collect remaining (interrupt) deferred exceptions + * using TXDEFR + * - Replace the triggers (from TXSTATI) with the int deferred + * exceptions DEFR ..., TXSTATI would have returned if it was valid + * from bgnd code + * - Reconstruct TXDEFR by or'ing bgnd deferred exceptions (except + * the DEFER bit) and the int deferred exceptions. This will be + * restored later + */ + DEFR D0.5, TXSTAT + MOV D1.5, TXDEFR + ANDT D0.5, D0.5, #HI(0xFFFF0000) + MOV D1Ar3, D1.5 + ANDT D1Ar3, D1Ar3, #HI(0xFFFF0000) + OR D0Ar4, D1Ar3, #TXSTAT_DEFER_BIT + OR D1.5, D1.5, D0.5 + + /* Mask off anything unrelated to the deferred exception triggers */ + ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS) + + /* Can assume that at least one exception happened since this + * handler wouldnt have been called otherwise. + * + * Replace the signal number and at the same time, prepare + * the mask to acknowledge the exception + * + * D1Re0 -- The bits to acknowledge + * D1Ar3 -- The signal number + * D1RtP -- Scratch to deal with non-conditional insns + */ + MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT) + MOV D1RtP, #TXSTAT_FPE_INVALID_S + FFB D1Ar3, D1Ar3 + CMP D1Ar3, #TXSTAT_FPE_INVALID_S + MOVLE D1Ar3, D1RtP /* Collapse FPE triggers to a single signal */ + MOV D1RtP, #1 + LSLGT D1Re0, D1RtP, D1Ar3 + + /* Get the handler using the signal number + * + * D1Ar3 -- The signal number + * D0Re0 -- Offset into TBI struct containing handler address + * D1Re0 -- Mask of triggers to keep + * D1RtP -- Address of handler + */ + SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE) + LSL D0Re0, D1Ar3, #2 + XOR D1Re0, D1Re0, #-1 /* Prepare mask for acknowledge (avoids stall) */ + ADD D0Re0,D0Re0,#TBI_fnSigs + GETD D1RtP, [D0Ar6+D0Re0] + + /* Acknowledge triggers */ + AND D1.5, D1.5, D1Re0 + + /* Restore remaining exceptions + * Do this here in case the handler enables nested interrupts + * + * D1.5 -- TXDEFR with this exception ack'd + */ + MOV TXDEFR, D1.5 + + /* Call the handler */ + SWAP D1RtP, PC + + GETL D0.5, D1.5, [--A0StP] + GETL D0FrT, D1RtP, [--A0StP] + MOV PC,D1RtP +#else /* META_BUG_MBN100212 */ + + /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved + * D0Ar4 -- The deferred exceptions + * D1Ar3 -- As per D0Ar4 but just the trigger bits + */ + + /* - Collect the pending deferred exceptions using TXSTAT, + * (ack's the interrupt exceptions as a side-effect) + */ + DEFR D0Ar4, TXSTATI + + /* Mask off anything unrelated to the deferred exception triggers */ + MOV D1Ar3, D0Ar4 + ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS) + + /* Can assume that at least one exception happened since this + * handler wouldnt have been called otherwise. + * + * Replace the signal number and at the same time, prepare + * the mask to acknowledge the exception + * + * The unusual code for 1<<D1Ar3 may need explanation. + * Normally this would be done using 'MOV rs,#1' and 'LSL rd,rs,D1Ar3' + * but only D1Re0 is available in D1 and no crossunit insns are available + * Even worse, there is no conditional 'MOV r,#uimm8'. + * Since the CMP proves that D1Ar3 >= 20, we can reuse the bottom 12-bits + * of D1Re0 (using 'ORGT r,#1') in the knowledge that the top 20-bits will + * be discarded without affecting the result. + * + * D1Re0 -- The bits to acknowledge + * D1Ar3 -- The signal number + */ + MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT) + MOV D0Re0, #TXSTAT_FPE_INVALID_S + FFB D1Ar3, D1Ar3 + CMP D1Ar3, #TXSTAT_FPE_INVALID_S + MOVLE D1Ar3, D0Re0 /* Collapse FPE triggers to a single signal */ + ORGT D1Re0, D1Re0, #1 + LSLGT D1Re0, D1Re0, D1Ar3 + + SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE) + + /* Acknowledge triggers and restore remaining exceptions + * Do this here in case the handler enables nested interrupts + * + * (x | y) ^ y == x & ~y. It avoids the restrictive XOR ...,#-1 insn + * and is the same length + */ + MOV D0Re0, TXDEFR + OR D0Re0, D0Re0, D1Re0 + XOR TXDEFR, D0Re0, D1Re0 + + /* Get the handler using the signal number + * + * D1Ar3 -- The signal number + * D0Re0 -- Address of handler + */ + LSL D0Re0, D1Ar3, #2 + ADD D0Re0,D0Re0,#TBI_fnSigs + GETD D0Re0, [D0Ar6+D0Re0] + + /* Tailcall the handler */ + MOV PC,D0Re0 + +#endif /* META_BUG_MBN100212 */ + .size ___TBIHandleDFR,.-___TBIHandleDFR +/* + * End of tbidefr.S + */ |