arm: add software reboot for QEMU
This simulates a reboot by jumping back to the address stored in the reset vector in vector table found at address 0. It is supported from interrupt/exception level, which means that sys_arch_reboot() in this case finds out if it is called from thread mode or handler mode, and in the latter case, it unwinds the nested exception stack as needed. Change-Id: Ib67f850f8411f1ee8fc592a5f31f2f70d0af14a4 Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
parent
62c65d7f00
commit
c5bb958db4
2 changed files with 96 additions and 10 deletions
|
@ -27,6 +27,7 @@
|
|||
#include <toolchain.h>
|
||||
#include <sections.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <offsets.h>
|
||||
#include "vector_table.h"
|
||||
|
||||
_ASM_FILE_PROLOGUE
|
||||
|
@ -87,3 +88,53 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
|
|||
#endif
|
||||
|
||||
b _PrepC
|
||||
|
||||
#if defined(CONFIG_SOC_TI_LM3S6965_QEMU)
|
||||
|
||||
GTEXT(_do_software_reboot)
|
||||
SECTION_FUNC(TEXT,_do_software_reboot)
|
||||
|
||||
eors r0, r0
|
||||
|
||||
/* move exception table back to 0 */
|
||||
ldr r1, =0xe000e000
|
||||
str r0, [r1, #0xd08] /* VTOR */
|
||||
|
||||
ldr r0, [r0, #4]
|
||||
bx r0
|
||||
|
||||
|
||||
GTEXT(_force_exit_one_nested_irq)
|
||||
SECTION_FUNC(TEXT,_force_exit_one_nested_irq)
|
||||
|
||||
ldr r0, =_SCS_ICSR_RETTOBASE
|
||||
ldr r1, =_SCS_ICSR
|
||||
ldr r1, [r1]
|
||||
ands.w r0, r1
|
||||
|
||||
/*
|
||||
* If Z flag is set, we are nested, so un-nest one level and get back to
|
||||
* this function to unwind the next level; else, exit the last interrupt
|
||||
* by jumping to reboot code.
|
||||
*/
|
||||
ittee eq
|
||||
ldreq lr, =0xfffffff1
|
||||
ldreq r2, =_force_exit_one_nested_irq
|
||||
ldrne lr, =0xfffffffd
|
||||
ldrne r2, =_do_software_reboot
|
||||
|
||||
ldr ip, =_interrupt_stack
|
||||
add.w ip, #(__tESF_SIZEOF * 2) /* enough for a stack frame */
|
||||
ldr r1, =0xfffffffe
|
||||
and.w r2, r1
|
||||
str r2, [ip, #(6 * 4)]
|
||||
ldr r2, =0x01000000
|
||||
str r2, [ip, #(7 * 4)]
|
||||
|
||||
ite eq
|
||||
moveq sp, ip
|
||||
msrne PSP, ip
|
||||
|
||||
bx lr
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,20 +30,38 @@
|
|||
|
||||
#define SCB_AIRCR_VECTKEY_EN_W 0x05FA
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reset the system
|
||||
*
|
||||
* This routine resets the processor.
|
||||
*
|
||||
* @return N/A
|
||||
#if defined(CONFIG_SOC_TI_LM3S6965_QEMU)
|
||||
/*
|
||||
* QEMU is missing the support for rebooting through the SYSRESETREQ mechanism.
|
||||
* Just jump back to __reset() of the image in flash, which address can
|
||||
* _always_ be found in the vector table reset slot located at address 0x4.
|
||||
*/
|
||||
void sys_arch_reboot(int type)
|
||||
|
||||
static void software_reboot(void)
|
||||
{
|
||||
extern void _do_software_reboot(void);
|
||||
extern void _force_exit_one_nested_irq(void);
|
||||
/*
|
||||
* force enable interrupts locked via PRIMASK if somehow disabled: the
|
||||
* boot code does not enable them
|
||||
*/
|
||||
__asm__ volatile("cpsie i" :::);
|
||||
|
||||
if (_ScbIsInThreadMode()) {
|
||||
_do_software_reboot();
|
||||
} else {
|
||||
__asm__ volatile(
|
||||
"ldr r0, =_force_exit_one_nested_irq\n\t"
|
||||
"bx r0\n\t"
|
||||
:::);
|
||||
}
|
||||
}
|
||||
#define DO_REBOOT() software_reboot()
|
||||
#else
|
||||
static void reboot_through_sysresetreq(void)
|
||||
{
|
||||
union __aircr reg;
|
||||
|
||||
ARG_UNUSED(type);
|
||||
|
||||
reg.val = __scs.scb.aircr.val;
|
||||
reg.bit.vectkey = SCB_AIRCR_VECTKEY_EN_W;
|
||||
reg.bit.sysresetreq = 1;
|
||||
|
@ -54,6 +72,23 @@ void sys_arch_reboot(int type)
|
|||
;
|
||||
}
|
||||
}
|
||||
#define DO_REBOOT() reboot_through_sysresetreq()
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reset the system
|
||||
*
|
||||
* This routine resets the processor.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void sys_arch_reboot(int type)
|
||||
{
|
||||
ARG_UNUSED(type);
|
||||
DO_REBOOT();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue