102 lines
5.4 KiB
C
102 lines
5.4 KiB
C
/*
|
|
* Copyright 2015 Dius Computing Pty Ltd. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
* - Neither the name of the copyright holders nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* @author Johny Mattsson <jmattsson@dius.com.au>
|
|
*/
|
|
|
|
/* Minimal handler function for 8/16bit loads from the mapped SPI flash.
|
|
* Called from the overridden UserExceptionVector on exception cause 3.
|
|
*/
|
|
asm(
|
|
".section \".iram0.text\"\n"
|
|
" .align 4\n"
|
|
"store_mask:\n"
|
|
" .word 0x004000\n" /* bit 14 is set on store instructions (see note ^) */
|
|
"align_mask:\n"
|
|
" .word ~3\n" /* mask to get 32bit alignment of addresses */
|
|
".type cause3_handler,@function\n"
|
|
"cause3_handler:\n"
|
|
" wsr a2, EXCSAVE2\n" /* free up a2 for use too */
|
|
" rsr a2, EPC1\n" /* get the program counter that caused the exception */
|
|
" ssa8l a2\n" /* prepare to extract the (unaligned) instruction */
|
|
" l32r a0, align_mask\n"/* prepare mask for 32bit alignment */
|
|
" and a2, a2, a0\n" /* get aligned base address of instruction */
|
|
" l32i a0, a2, 0\n" /* load first part */
|
|
" l32i a2, a2, 4\n" /* load second part */
|
|
" src a0, a2, a0\n" /* faulting instruction now in a0 */
|
|
" l32r a2, store_mask\n"
|
|
" and a0, a0, a2\n" /* test for store bit */
|
|
" bnez a0, 1f\n" /* it's a store, we don't do stores, get out */
|
|
|
|
"" /* As it turns out, the ESP8266 happily does 8/16bit */
|
|
/* loads from the mapped SPI flash, but then raises an */
|
|
/* exception anyway; we can simply increment the */
|
|
/* program counter and be our merry way, safe in */
|
|
/* the knowledge that the loads have already been done.*/
|
|
/* Note that this only applies to the SPI flash, not */
|
|
/* internal ROM or IRAM - if we ever want to support */
|
|
/* those we'll need to add the appropriate loading */
|
|
/* logic here. For now I see no need for such support. */
|
|
|
|
" rsr a2, EPC1\n" /* read the program counter again */
|
|
" addi a2, a2, 3\n" /* advance program counter past faulting instruction */
|
|
" wsr a2, EPC1\n" /* and store it back */
|
|
" rsr a2, EXCSAVE2\n" /* restore a2 */
|
|
" rsr a0, EXCSAVE1\n" /* restore a0 */
|
|
" rfe\n" /* and done! */
|
|
"1:rsr a2, EXCSAVE2\n" /* we're about to chain, so restore the a2 we clobbered*/
|
|
" ret\n" /* and hop back into the exception vector code */
|
|
);
|
|
/* Note ^) Except for the S32E instruction, but that's not applicable here,
|
|
* so we can happily ignore it.
|
|
*/
|
|
|
|
|
|
|
|
/* Our sneaky override of the UserExceptionVector to allow us to handle 8/16bit
|
|
* loads from SPI flash. MUST BE >= 32bytes compiled, as the next vector starts
|
|
* there.
|
|
*/
|
|
asm(
|
|
".section \".UserExceptionVectorOverride.text\"\n"
|
|
".type _UserExceptionVectorOverride,@function\n"
|
|
".globl _UserExceptionVectorOverride\n"
|
|
"_UserExceptionVectorOverride:\n"
|
|
" wsr a0, EXCSAVE1\n" /* free up a0 for a while */
|
|
" rsr a0, EXCCAUSE\n" /* get the exception cause */
|
|
" bnei a0, 3, 2f\n" /* if not EXCCAUSE_LOAD_STORE_ERROR, chain to rtos */
|
|
" j 1f\n" /* jump past noncode bytes for cause3_handler addr */
|
|
" .align 4\n" /* proper alignment for literals */
|
|
" .literal_position\n" /* the linker will put cause3_handler addr here */
|
|
"1:call0 cause3_handler\n" /* handle loads and rfe, stores will return here */
|
|
"2:rsr a0, EXCSAVE1\n" /* restore a0 before we chain */
|
|
" j _UserExceptionVector\n" /* and off we go to rtos */
|
|
);
|