Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
947068cd
Commit
947068cd
authored
Jun 24, 2015
by
devsaurus
Browse files
Merge pull request #3 from DiUS/loadnon32
Loadnon32
parents
58081e59
b0f9788a
Changes
8
Hide whitespace changes
Inline
Side-by-side
app/Makefile
View file @
947068cd
...
...
@@ -99,7 +99,7 @@ LINKFLAGS_eagle.app.v6 = \
-nostdlib
\
-T
$(LD_FILE)
\
-Wl
,--no-check-sections
\
-u
call_user_start
\
-Wl
,--wrap
=
_xtos_set_exception_handler
\
-Wl
,-static
\
-Wl
,--start-group
\
-lc
\
...
...
app/include/rom.h
View file @
947068cd
...
...
@@ -37,3 +37,57 @@ extern unsigned char * base64_decode(const unsigned char *src, size_t len, size_
// initialized because it uses mem_malloc
extern
void
mem_init
(
void
*
start_addr
);
// Hardware exception handling
struct
exception_frame
{
uint32_t
epc
;
uint32_t
ps
;
uint32_t
sar
;
uint32_t
unused
;
union
{
struct
{
uint32_t
a0
;
// note: no a1 here!
uint32_t
a2
;
uint32_t
a3
;
uint32_t
a4
;
uint32_t
a5
;
uint32_t
a6
;
uint32_t
a7
;
uint32_t
a8
;
uint32_t
a9
;
uint32_t
a10
;
uint32_t
a11
;
uint32_t
a12
;
uint32_t
a13
;
uint32_t
a14
;
uint32_t
a15
;
};
uint32_t
a_reg
[
15
];
};
uint32_t
cause
;
};
/**
* C-level exception handler callback prototype.
*
* Does not need an RFE instruction - it is called through a wrapper which
* performs state capture & restore, as well as the actual RFE.
*
* @param ef An exception frame containing the relevant state from the
* exception triggering. This state may be manipulated and will
* be applied on return.
* @param cause The exception cause number.
*/
typedef
void
(
*
exception_handler_fn
)
(
struct
exception_frame
*
ef
,
uint32_t
cause
);
/**
* Sets the exception handler function for a particular exception cause.
* @param handler The exception handler to install.
* If NULL, reverts to the XTOS default handler.
* @returns The previous exception handler, or NULL if none existed prior.
*/
exception_handler_fn
_xtos_set_exception_handler
(
uint32_t
cause
,
exception_handler_fn
handler
);
app/user/user_exceptions.c
0 → 100644
View file @
947068cd
/*
* 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>
*/
#include "user_exceptions.h"
#define LOAD_MASK 0x00f00fu
#define L8UI_MATCH 0x000002u
#define L16UI_MATCH 0x001002u
#define L16SI_MATCH 0x009002u
void
load_non_32_wide_handler
(
struct
exception_frame
*
ef
,
uint32_t
cause
)
{
/* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
(
void
)
cause
;
uint32_t
epc1
=
ef
->
epc
;
uint32_t
excvaddr
;
uint32_t
insn
;
asm
(
"rsr %0, EXCVADDR;"
/* read out the faulting address */
"movi a4, ~3;"
/* prepare a mask for the EPC */
"and a4, a4, %2;"
/* apply mask for 32bit aligned base */
"l32i a5, a4, 0;"
/* load part 1 */
"l32i a6, a4, 4;"
/* load part 2 */
"ssa8l %2;"
/* set up shift register for src op */
"src %1, a6, a5;"
/* right shift to get faulting instruction */
:
"=r"
(
excvaddr
),
"=r"
(
insn
)
:
"r"
(
epc1
)
:
"a4"
,
"a5"
,
"a6"
);
uint32_t
valmask
=
0
;
uint32_t
what
=
insn
&
LOAD_MASK
;
if
(
what
==
L8UI_MATCH
)
valmask
=
0xffu
;
else
if
(
what
==
L16UI_MATCH
||
what
==
L16SI_MATCH
)
valmask
=
0xffffu
;
else
{
die:
/* Turns out we couldn't fix this, trigger a system break instead
* and hang if the break doesn't get handled. This is effectively
* what would happen if the default handler was installed. */
asm
(
"break 1, 1"
);
while
(
1
)
{}
}
/* Load, shift and mask down to correct size */
uint32_t
val
=
(
*
(
uint32_t
*
)(
excvaddr
&
~
0x3
));
val
>>=
(
excvaddr
&
0x3
)
*
8
;
val
&=
valmask
;
/* Sign-extend for L16SI, if applicable */
if
(
what
==
L16SI_MATCH
&&
(
val
&
0x8000
))
val
|=
0xffff0000
;
int
regno
=
(
insn
&
0x0000f0u
)
>>
4
;
if
(
regno
==
1
)
goto
die
;
/* we can't support loading into a1, just die */
else
if
(
regno
!=
0
)
--
regno
;
/* account for skipped a1 in exception_frame */
ef
->
a_reg
[
regno
]
=
val
;
/* carry out the load */
ef
->
epc
+=
3
;
/* resume at following instruction */
}
/**
* The SDK's user_main function installs a debugging handler regardless
* of whether there's a proper handler installed for EXCCAUSE_LOAD_STORE_ERROR,
* which of course breaks everything if we allow that to go through. As such,
* we use the linker to wrap that call and stop the SDK from shooting itself in
* its proverbial foot.
*/
exception_handler_fn
__wrap__xtos_set_exception_handler
(
uint32_t
cause
,
exception_handler_fn
fn
)
{
if
(
cause
!=
EXCCAUSE_LOAD_STORE_ERROR
)
__real__xtos_set_exception_handler
(
cause
,
fn
);
}
app/user/user_exceptions.h
0 → 100644
View file @
947068cd
#include "c_types.h"
#include "rom.h"
#include <xtensa/corebits.h>
void
load_non_32_wide_handler
(
struct
exception_frame
*
ef
,
uint32_t
cause
)
TEXT_SECTION_ATTR
;
app/user/user_main.c
View file @
947068cd
...
...
@@ -16,6 +16,7 @@
#include "flash_fs.h"
#include "user_interface.h"
#include "user_exceptions.h"
#include "ets_sys.h"
#include "driver/uart.h"
...
...
@@ -25,6 +26,21 @@
#define TASK_QUEUE_LEN 4
os_event_t
*
taskQueue
;
/* Note: the trampoline *must* be explicitly put into the .text segment, since
* by the time it is invoked the irom has not yet been mapped. This naturally
* also goes for anything the trampoline itself calls.
*/
void
user_start_trampoline
(
void
)
TEXT_SECTION_ATTR
;
void
user_start_trampoline
(
void
)
{
__real__xtos_set_exception_handler
(
EXCCAUSE_LOAD_STORE_ERROR
,
load_non_32_wide_handler
);
call_user_start
();
}
void
task_lua
(
os_event_t
*
e
){
char
*
lua_argv
[]
=
{
(
char
*
)
"lua"
,
(
char
*
)
"-i"
,
NULL
};
NODE_DBG
(
"Task task_lua started.
\n
"
);
...
...
include/c_types.h
View file @
947068cd
...
...
@@ -84,6 +84,9 @@ typedef enum {
#define ICACHE_FLASH_ATTR
#endif
/* ICACHE_FLASH */
#define TEXT_SECTION_ATTR __attribute__((section(".text")))
#define RAM_CONST_ATTR __attribute__((section(".text")))
#ifndef __cplusplus
typedef
unsigned
char
bool
;
#define BOOL bool
...
...
ld/eagle.app.v6.ld
View file @
947068cd
...
...
@@ -19,7 +19,7 @@ PHDRS
/* Default entry point: */
ENTRY(
call_
user_start)
ENTRY(user_start
_trampoline
)
PROVIDE(_memmap_vecbase_reset = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
...
...
@@ -75,6 +75,10 @@ SECTIONS
/* put font and progmem data into irom0 */
*(.u8g_progmem.*)
/* Trade some performance for lots of ram. At the time of writing the
* available Lua heap went from 18248 to 34704. */
*(.rodata*)
_irom0_text_end = ABSOLUTE(.);
_flash_used_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
...
...
@@ -124,10 +128,7 @@ SECTIONS
.rodata : ALIGN(4)
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
...
...
tools/esptool.py
View file @
947068cd
...
...
@@ -360,6 +360,20 @@ class ELFFile:
self
.
_fetch_symbols
()
return
self
.
symbols
[
sym
]
def
get_entry_point
(
self
):
tool_readelf
=
"xtensa-lx106-elf-readelf"
if
os
.
getenv
(
'XTENSA_CORE'
)
==
'lx106'
:
tool_objcopy
=
"xt-readelf"
try
:
proc
=
subprocess
.
Popen
([
tool_readelf
,
"-h"
,
self
.
name
],
stdout
=
subprocess
.
PIPE
)
except
OSError
:
print
"Error calling "
+
tool_nm
+
", do you have Xtensa toolchain in PATH?"
sys
.
exit
(
1
)
for
l
in
proc
.
stdout
:
fields
=
l
.
strip
().
split
()
if
fields
[
0
]
==
"Entry"
:
return
int
(
fields
[
3
],
0
);
def
load_section
(
self
,
section
):
tool_objcopy
=
"xtensa-lx106-elf-objcopy"
if
os
.
getenv
(
'XTENSA_CORE'
)
==
'lx106'
:
...
...
@@ -586,7 +600,7 @@ if __name__ == '__main__':
args
.
output
=
args
.
input
+
'-'
e
=
ELFFile
(
args
.
input
)
image
=
ESPFirmwareImage
()
image
.
entrypoint
=
e
.
get_
symbol_addr
(
"call_user_start"
)
image
.
entrypoint
=
e
.
get_
entry_point
(
)
for
section
,
start
in
((
".text"
,
"_text_start"
),
(
".data"
,
"_data_start"
),
(
".rodata"
,
"_rodata_start"
)):
data
=
e
.
load_section
(
section
)
image
.
add_segment
(
e
.
get_symbol_addr
(
start
),
data
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment