Merge pull request #131 from karlp/wdreset
Provide a wrapper for reset via watchdog Tested-By: Priit Laes plaes@plaes.org # On A20 with custom patch
This commit is contained in:
commit
ce6897eaa7
17
fel.c
17
fel.c
@ -1055,6 +1055,20 @@ void aw_rmr_request(feldev_handle *dev, uint32_t entry_point, bool aarch64)
|
||||
pr_info(" done.\n");
|
||||
}
|
||||
|
||||
/* Use the watchdog to simply reboot. Useful to get out of fel without
|
||||
* power cycling or plugging.
|
||||
*/
|
||||
void aw_wd_reset(feldev_handle *dev)
|
||||
{
|
||||
const watchdog_info *wd = dev->soc_info->watchdog;
|
||||
if (!wd) {
|
||||
pr_error("No watchdog information available (yet) for soc: %s\n", dev->soc_info->name);
|
||||
return;
|
||||
}
|
||||
fel_writel(dev, wd->reg_mode, wd->reg_mode_value);
|
||||
pr_info("Requested watchdog reset\n");
|
||||
}
|
||||
|
||||
/* check buffer for magic "#=uEnv", indicating uEnv.txt compatible format */
|
||||
static bool is_uEnv(void *buffer, size_t size)
|
||||
{
|
||||
@ -1164,6 +1178,7 @@ void usage(const char *cmd) {
|
||||
" dump address length Binary memory dump\n"
|
||||
" exe[cute] address Call function address\n"
|
||||
" reset64 address RMR request for AArch64 warm boot\n"
|
||||
" wdreset Reboot via watchdog\n"
|
||||
" memmove dest source size Copy <size> bytes within device memory\n"
|
||||
" readl address Read 32-bit value from device memory\n"
|
||||
" writel address value Write 32-bit value to device memory\n"
|
||||
@ -1296,6 +1311,8 @@ int main(int argc, char **argv)
|
||||
/* Cancel U-Boot autostart, and stop processing args */
|
||||
uboot_autostart = false;
|
||||
break;
|
||||
} else if (strcmp(argv[1], "wdreset") == 0) {
|
||||
aw_wd_reset(handle);
|
||||
} else if (strncmp(argv[1], "ver", 3) == 0) {
|
||||
aw_fel_print_version(handle);
|
||||
} else if (strcmp(argv[1], "sid") == 0) {
|
||||
|
||||
13
soc_info.c
13
soc_info.c
@ -110,6 +110,16 @@ sram_swap_buffers h6_sram_swap_buffers[] = {
|
||||
{ .size = 0 } /* End of the table */
|
||||
};
|
||||
|
||||
const watchdog_info wd_a10_compat = {
|
||||
.reg_mode = 0x01C20C94,
|
||||
.reg_mode_value = 3,
|
||||
};
|
||||
|
||||
const watchdog_info wd_h3_compat = {
|
||||
.reg_mode = 0x01C20Cb8,
|
||||
.reg_mode_value = 1,
|
||||
};
|
||||
|
||||
soc_info_t soc_info_table[] = {
|
||||
{
|
||||
.soc_id = 0x1623, /* Allwinner A10 */
|
||||
@ -119,6 +129,7 @@ soc_info_t soc_info_table[] = {
|
||||
.swap_buffers = a10_a13_a20_sram_swap_buffers,
|
||||
.needs_l2en = true,
|
||||
.sid_base = 0x01C23800,
|
||||
.watchdog = &wd_a10_compat,
|
||||
},{
|
||||
.soc_id = 0x1625, /* Allwinner A10s, A13, R8 */
|
||||
.name = "A13",
|
||||
@ -195,6 +206,7 @@ soc_info_t soc_info_table[] = {
|
||||
.sid_fix = true,
|
||||
/* Check L.NOP in the OpenRISC reset vector */
|
||||
.needs_smc_workaround_if_zero_word_at_addr = 0x40004,
|
||||
.watchdog = &wd_h3_compat,
|
||||
},{
|
||||
.soc_id = 0x1681, /* Allwinner V3s */
|
||||
.name = "V3s",
|
||||
@ -215,6 +227,7 @@ soc_info_t soc_info_table[] = {
|
||||
.rvbar_reg = 0x017000A0,
|
||||
/* Check L.NOP in the OpenRISC reset vector */
|
||||
.needs_smc_workaround_if_zero_word_at_addr = 0x40004,
|
||||
.watchdog = &wd_h3_compat,
|
||||
},{
|
||||
.soc_id = 0x1701, /* Allwinner R40 */
|
||||
.name = "R40",
|
||||
|
||||
11
soc_info.h
11
soc_info.h
@ -51,6 +51,16 @@ typedef struct {
|
||||
uint32_t size; /* buffer size */
|
||||
} sram_swap_buffers;
|
||||
|
||||
/*
|
||||
* Contains information on the watchdog peripheral, to enable reset
|
||||
*/
|
||||
typedef struct {
|
||||
/* Register that needs to be written to */
|
||||
uint32_t reg_mode;
|
||||
/* Value to write to trigger a reset */
|
||||
uint32_t reg_mode_value;
|
||||
} watchdog_info;
|
||||
|
||||
/*
|
||||
* Each SoC variant may have its own list of memory buffers to be exchanged
|
||||
* and the information about the placement of the thunk code, which handles
|
||||
@ -101,6 +111,7 @@ typedef struct {
|
||||
uint32_t sid_base; /* base address for SID registers */
|
||||
uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */
|
||||
uint32_t rvbar_reg; /* MMIO address of RVBARADDR0_L register */
|
||||
const watchdog_info *watchdog; /* Used for reset */
|
||||
bool sid_fix; /* Use SID workaround (read via register) */
|
||||
/* Use SMC workaround (enter secure mode) if can't read from this address */
|
||||
uint32_t needs_smc_workaround_if_zero_word_at_addr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user