|
| 1 | +// exc-c-wrapper-handler.S, this is a reduced version of the original file at |
| 2 | +// https://github.com/qca/open-ath9k-htc-firmware/blob/master/sboot/magpie_1_1/sboot/athos/src/xtos/exc-c-wrapper-handler.S#L62-L67 |
| 3 | +// |
| 4 | + |
| 5 | +// exc-c-wrapper-handler.S - General Exception Handler that Dispatches C Handlers |
| 6 | + |
| 7 | +// Copyright (c) 2002-2004, 2006-2007, 2010 Tensilica Inc. |
| 8 | +// |
| 9 | +// Permission is hereby granted, free of charge, to any person obtaining |
| 10 | +// a copy of this software and associated documentation files (the |
| 11 | +// "Software"), to deal in the Software without restriction, including |
| 12 | +// without limitation the rights to use, copy, modify, merge, publish, |
| 13 | +// distribute, sublicense, and/or sell copies of the Software, and to |
| 14 | +// permit persons to whom the Software is furnished to do so, subject to |
| 15 | +// the following conditions: |
| 16 | +// |
| 17 | +// The above copyright notice and this permission notice shall be included |
| 18 | +// in all copies or substantial portions of the Software. |
| 19 | +// |
| 20 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 21 | +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 22 | +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 23 | +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| 24 | +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| 25 | +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| 26 | +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 27 | + |
| 28 | +#include <xtensa/coreasm.h> |
| 29 | +#include <xtensa/corebits.h> |
| 30 | +#include <xtensa/config/specreg.h> |
| 31 | +// #include "xtos-internal.h" |
| 32 | +// #ifdef SIMULATOR |
| 33 | +// #include <xtensa/simcall.h> |
| 34 | +// #endif |
| 35 | + |
| 36 | +#include "xtruntime-frames.h" |
| 37 | + |
| 38 | +/* |
| 39 | + * This is the general exception assembly-level handler that dispatches C handlers. |
| 40 | + */ |
| 41 | + .align 4 |
| 42 | + .global _xtos_c_wrapper_handler |
| 43 | +_xtos_c_wrapper_handler: |
| 44 | + |
| 45 | + // HERE: a2, a3, a4 have been saved to exception stack frame allocated with a1 (sp). |
| 46 | + // a2 contains EXCCAUSE. |
| 47 | + s32i a5, a1, UEXC_a5 // a5 will get clobbered by ENTRY after the pseudo-CALL4 |
| 48 | + // (a4..a15 spilled as needed; save if modified) |
| 49 | + |
| 50 | + //NOTA: Possible future improvement: |
| 51 | + // keep interrupts disabled until we get into the handler, such that |
| 52 | + // we don't have to save other critical state such as EXCVADDR here. |
| 53 | +// @mhightower83 - This promise was broken by an "rsil a13, 0" below. |
| 54 | + //rsr a3, EXCVADDR |
| 55 | + s32i a2, a1, UEXC_exccause |
| 56 | + //s32i a3, a1, UEXC_excvaddr |
| 57 | + |
| 58 | + // Set PS fields: |
| 59 | + // EXCM = 0 |
| 60 | + // WOE = __XTENSA_CALL0_ABI__ ? 0 : 1 |
| 61 | + // UM = 1 |
| 62 | + // INTLEVEL = EXCM_LEVEL = 1 |
| 63 | + // CALLINC = __XTENSA_CALL0_ABI__ ? 0 : 1 |
| 64 | + // OWB = 0 (really, a dont care if !__XTENSA_CALL0_ABI__) |
| 65 | + |
| 66 | + movi a2, 0x23 // 0x21, PS_UM|PS_INTLEVEL(XCHAL_EXCM_LEVEL) |
| 67 | + rsr a3, EPC_1 |
| 68 | +// @mhightower83 - I assume PS.EXCM was set and now is being cleared, thus |
| 69 | +// allowing new exceptions and interrupts within PS_INTLEVEL to be possible. |
| 70 | + xsr a2, PS |
| 71 | + |
| 72 | + // HERE: window overflows enabled, but NOT SAFE because we're not quite |
| 73 | + // in a valid windowed context (haven't restored a1 yet...); |
| 74 | + // so don't cause any (keep to a0..a3) until we've saved critical state and restored a1: |
| 75 | + |
| 76 | + // NOTE: MUST SAVE EPC1 before causing any overflows, because overflows corrupt EPC1. |
| 77 | + s32i a3, a1, UEXC_pc |
| 78 | + s32i a2, a1, UEXC_ps |
| 79 | + s32i a0, a1, UEXC_a0 // save the rest of the registers |
| 80 | + s32i a6, a1, UEXC_a6 |
| 81 | + s32i a7, a1, UEXC_a7 |
| 82 | + s32i a8, a1, UEXC_a8 |
| 83 | + s32i a9, a1, UEXC_a9 |
| 84 | + s32i a10, a1, UEXC_a10 |
| 85 | + s32i a11, a1, UEXC_a11 |
| 86 | + s32i a12, a1, UEXC_a12 |
| 87 | + s32i a13, a1, UEXC_a13 |
| 88 | + s32i a14, a1, UEXC_a14 |
| 89 | + s32i a15, a1, UEXC_a15 |
| 90 | + rsync // wait for WSR to PS to complete |
| 91 | + rsr a12, SAR |
| 92 | + |
| 93 | +// @mhightower83 - I think after the next instruction we have the potential of |
| 94 | +// loosing UEXC_excvaddr Which the earlier comment said we need to preserve for |
| 95 | +// the exception handler. |
| 96 | +// |
| 97 | +// rsil a13, 0 |
| 98 | + |
| 99 | + movi a13, _xtos_c_handler_table // &table |
| 100 | + l32i a15, a1, UEXC_exccause // arg2: exccause |
| 101 | + s32i a12, a1, UEXC_sar |
| 102 | + addx4 a12, a15, a13 // a12 = table[exccause] |
| 103 | + l32i a12, a12, 0 // ... |
| 104 | + mov a2, a1 // arg1: exception parameters |
| 105 | + mov a3, a15 // arg2: exccause |
| 106 | + beqz a12, 1f // null handler => skip call |
| 107 | + callx0 a12 // call C exception handler for this exception |
| 108 | +1: |
| 109 | + // Now exit the handler. |
| 110 | + |
| 111 | + // Restore special registers |
| 112 | + l32i a14, a1, UEXC_sar |
| 113 | + |
| 114 | + /* |
| 115 | + * Disable interrupts while returning from the pseudo-CALL setup above, |
| 116 | + * for the same reason they were disabled while doing the pseudo-CALL: |
| 117 | + * this sequence restores SP such that it doesn't reflect the allocation |
| 118 | + * of the exception stack frame, which we still need to return from |
| 119 | + * the exception. |
| 120 | + */ |
| 121 | +// rsil a12, 1 // XCHAL_EXCM_LEVEL |
| 122 | + wsr a14, SAR |
| 123 | + movi a0, _xtos_return_from_exc |
| 124 | + jx a0 |
| 125 | + |
| 126 | + /* FIXME: what about _GeneralException ? */ |
| 127 | + .size _xtos_c_wrapper_handler, . - _xtos_c_wrapper_handler |
0 commit comments