diff --git a/hw/top_chip/dv/top_chip_sim_cfg.hjson b/hw/top_chip/dv/top_chip_sim_cfg.hjson index 1592ae70..17eb6d09 100644 --- a/hw/top_chip/dv/top_chip_sim_cfg.hjson +++ b/hw/top_chip/dv/top_chip_sim_cfg.hjson @@ -167,6 +167,42 @@ run_opts: ["+ChipMemSRAM_image_file={run_dir}/rom_ctrl_smoketest_cheri_bare.vmem", "+ChipMemROM_image_file={proj_root}/sw/device/tests/rom_ctrl/mem_init_file.vmem"] } + { + name: rstmgr_smoke + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["rstmgr_software_reset_vanilla_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/rstmgr_software_reset_vanilla_bare.vmem"] + } + { + name: rstmgr_smoke_cheri + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["rstmgr_software_reset_cheri_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/rstmgr_software_reset_cheri_bare.vmem"] + } + { + name: clkmgr_smoke + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["clkmgr_smoketest_vanilla_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/clkmgr_smoketest_vanilla_bare.vmem"] + } + { + name: clkmgr_smoke_cheri + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["clkmgr_smoketest_cheri_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/clkmgr_smoketest_cheri_bare.vmem"] + } + { + name: pwrmgr_smoke + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["pwrmgr_smoketest_vanilla_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/pwrmgr_smoketest_vanilla_bare.vmem"] + } + { + name: pwrmgr_smoke_cheri + uvm_test_seq: top_chip_dv_base_vseq + sw_images: ["pwrmgr_smoketest_cheri_bare:5"] + run_opts: ["+ChipMemSRAM_image_file={run_dir}/pwrmgr_smoketest_cheri_bare.vmem"] + } { name: rv_dm_ndm_reset_req uvm_test_seq: "top_chip_dv_rv_dm_ndm_reset_req_vseq" @@ -255,6 +291,12 @@ "axi_sram_smoke_cheri", "rom_ctrl_smoke", "rom_ctrl_smoke_cheri", + "rstmgr_smoke", + "rstmgr_smoke_cheri", + "clkmgr_smoke", + "clkmgr_smoke_cheri", + "pwrmgr_smoke", + "pwrmgr_smoke_cheri", ] } { @@ -315,6 +357,27 @@ "rom_ctrl_smoke_cheri" ] } + { + name: rstmgr + tests: [ + "rstmgr_smoke", + "rstmgr_smoke_cheri" + ] + } + { + name: clkmgr + tests: [ + "clkmgr_smoke", + "clkmgr_smoke_cheri" + ] + } + { + name: pwrmgr + tests: [ + "pwrmgr_smoke", + "pwrmgr_smoke_cheri" + ] + } { name: rv_dm tests: [ diff --git a/sw/device/lib/hal/CMakeLists.txt b/sw/device/lib/hal/CMakeLists.txt index 6367223a..c19e6197 100644 --- a/sw/device/lib/hal/CMakeLists.txt +++ b/sw/device/lib/hal/CMakeLists.txt @@ -2,6 +2,6 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 -set(SRCS clkmgr.c gpio.c i2c.c mailbox.c mocha.c plic.c rom_ctrl.c rstmgr.c spi_device.c spi_host.c timer.c uart.c) +set(SRCS clkmgr.c gpio.c i2c.c mailbox.c mocha.c plic.c pwrmgr.c rom_ctrl.c rstmgr.c spi_device.c spi_host.c timer.c uart.c) mocha_add_library(NAME hal LIBRARIES SOURCES ${SRCS}) diff --git a/sw/device/lib/hal/clkmgr.c b/sw/device/lib/hal/clkmgr.c index 7132c8a1..217499a9 100644 --- a/sw/device/lib/hal/clkmgr.c +++ b/sw/device/lib/hal/clkmgr.c @@ -5,4 +5,57 @@ #include "hal/clkmgr.h" #include "hal/mmio.h" #include +#include #include + +static uint32_t clkmgr_read(clkmgr_t clkmgr, uintptr_t reg) +{ + return DEV_READ(clkmgr + reg); +} + +static void clkmgr_write(clkmgr_t clkmgr, uintptr_t reg, uint32_t value) +{ + DEV_WRITE(clkmgr + reg, value); +} + +static uint32_t clkmgr_bit(size_t clock) +{ + return 1u << clock; +} + +bool clkmgr_gateable_clock_get_enabled(clkmgr_t clkmgr, size_t clock) +{ + return (clkmgr_read(clkmgr, CLKMGR_CLK_ENABLES_REG) & clkmgr_bit(clock)) != 0; +} + +void clkmgr_gateable_clock_set_enabled(clkmgr_t clkmgr, size_t clock, bool enabled) +{ + uint32_t reg = clkmgr_read(clkmgr, CLKMGR_CLK_ENABLES_REG); + if (enabled) { + reg |= clkmgr_bit(clock); + } else { + reg &= ~clkmgr_bit(clock); + } + clkmgr_write(clkmgr, CLKMGR_CLK_ENABLES_REG, reg); +} + +bool clkmgr_hintable_clock_get_hint(clkmgr_t clkmgr, size_t clock) +{ + return (clkmgr_read(clkmgr, CLKMGR_CLK_HINTS_REG) & clkmgr_bit(clock)) != 0; +} + +void clkmgr_hintable_clock_set_hint(clkmgr_t clkmgr, size_t clock, bool enabled) +{ + uint32_t reg = clkmgr_read(clkmgr, CLKMGR_CLK_HINTS_REG); + if (enabled) { + reg |= clkmgr_bit(clock); + } else { + reg &= ~clkmgr_bit(clock); + } + clkmgr_write(clkmgr, CLKMGR_CLK_HINTS_REG, reg); +} + +bool clkmgr_hintable_clock_get_enabled(clkmgr_t clkmgr, size_t clock) +{ + return (clkmgr_read(clkmgr, CLKMGR_CLK_HINTS_STATUS_REG) & clkmgr_bit(clock)) != 0; +} diff --git a/sw/device/lib/hal/clkmgr.h b/sw/device/lib/hal/clkmgr.h index ff011000..4800473c 100644 --- a/sw/device/lib/hal/clkmgr.h +++ b/sw/device/lib/hal/clkmgr.h @@ -5,12 +5,26 @@ #pragma once #include +#include #include -#define CLKMGR_ALERT_TEST_REG (0x00) -#define CLKMGR_CLK_ENABLES_REG (0x18) -#define CLKMGR_CLK_ENABLES_ALL (1) +#define CLKMGR_ALERT_TEST_REG (0x00) +#define CLKMGR_JITTER_REGWEN_REG (0x10) +#define CLKMGR_JITTER_ENABLE_REG (0x14) +#define CLKMGR_CLK_ENABLES_REG (0x18) +#define CLKMGR_CLK_HINTS_REG (0x1c) +#define CLKMGR_CLK_HINTS_STATUS_REG (0x20) + +#define CLKMGR_GATEABLE_CLOCK_IO_PERI (0u) +#define CLKMGR_HINTABLE_CLOCK_MAIN (0u) typedef void *clkmgr_t; #define CLKMGR_FROM_BASE_ADDR(addr) ((clkmgr_t)(addr)) + +bool clkmgr_gateable_clock_get_enabled(clkmgr_t clkmgr, size_t clock); +void clkmgr_gateable_clock_set_enabled(clkmgr_t clkmgr, size_t clock, bool enabled); + +bool clkmgr_hintable_clock_get_hint(clkmgr_t clkmgr, size_t clock); +void clkmgr_hintable_clock_set_hint(clkmgr_t clkmgr, size_t clock, bool enabled); +bool clkmgr_hintable_clock_get_enabled(clkmgr_t clkmgr, size_t clock); diff --git a/sw/device/lib/hal/mocha.c b/sw/device/lib/hal/mocha.c index ed35f642..e6d02e79 100644 --- a/sw/device/lib/hal/mocha.c +++ b/sw/device/lib/hal/mocha.c @@ -17,6 +17,7 @@ static const uintptr_t dv_test_status_base = 0x20020000ul; static const uintptr_t gpio_base = 0x40000000ul; static const uintptr_t clkmgr_base = 0x40020000ul; static const uintptr_t rstmgr_base = 0x40030000ul; +static const uintptr_t pwrmgr_base = 0x40040000ul; static const uintptr_t rom_ctrl_base = 0x40050000ul; static const uintptr_t uart_base = 0x41000000ul; static const uintptr_t i2c_base = 0x42000000ul; @@ -90,6 +91,15 @@ rstmgr_t mocha_system_rstmgr(void) #endif /* defined(__riscv_zcherihybrid) */ } +pwrmgr_t mocha_system_pwrmgr(void) +{ +#if defined(__riscv_zcherihybrid) + return (pwrmgr_t)create_mmio_capability(pwrmgr_base, 0x80u); +#else /* !defined(__riscv_zcherihybrid) */ + return (pwrmgr_t)pwrmgr_base; +#endif /* defined(__riscv_zcherihybrid) */ +} + rom_ctrl_t mocha_system_rom_ctrl(void) { #if defined(__riscv_zcherihybrid) diff --git a/sw/device/lib/hal/mocha.h b/sw/device/lib/hal/mocha.h index 4db3f924..397a44ae 100644 --- a/sw/device/lib/hal/mocha.h +++ b/sw/device/lib/hal/mocha.h @@ -11,6 +11,7 @@ #include "hal/i2c.h" #include "hal/mailbox.h" #include "hal/plic.h" +#include "hal/pwrmgr.h" #include "hal/rom_ctrl.h" #include "hal/rstmgr.h" #include "hal/spi_device.h" @@ -36,6 +37,7 @@ mailbox_t mocha_system_mailbox(void); gpio_t mocha_system_gpio(void); clkmgr_t mocha_system_clkmgr(void); rstmgr_t mocha_system_rstmgr(void); +pwrmgr_t mocha_system_pwrmgr(void); rom_ctrl_t mocha_system_rom_ctrl(void); uart_t mocha_system_uart(void); i2c_t mocha_system_i2c(void); diff --git a/sw/device/lib/hal/pwrmgr.c b/sw/device/lib/hal/pwrmgr.c new file mode 100644 index 00000000..491e4952 --- /dev/null +++ b/sw/device/lib/hal/pwrmgr.c @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hal/pwrmgr.h" +#include "hal/mmio.h" +#include + +static uint32_t pwrmgr_read(pwrmgr_t pwrmgr, uintptr_t reg) +{ + return DEV_READ(pwrmgr + reg); +} + +static void pwrmgr_write(pwrmgr_t pwrmgr, uintptr_t reg, uint32_t value) +{ + DEV_WRITE(pwrmgr + reg, value); +} + +uint32_t pwrmgr_control_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_CONTROL_REG); +} + +void pwrmgr_control_set(pwrmgr_t pwrmgr, uint32_t value) +{ + pwrmgr_write(pwrmgr, PWRMGR_CONTROL_REG, value & PWRMGR_CONTROL_MASK); +} + +void pwrmgr_cfg_sync(pwrmgr_t pwrmgr) +{ + pwrmgr_write(pwrmgr, PWRMGR_CFG_CDC_SYNC_REG, 1u); + while ((pwrmgr_read(pwrmgr, PWRMGR_CFG_CDC_SYNC_REG) & 1u) != 0u) { + } +} + +uint32_t pwrmgr_wakeup_enable_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_WAKEUP_EN_REG); +} + +void pwrmgr_wakeup_enable_set(pwrmgr_t pwrmgr, uint32_t value) +{ + pwrmgr_write(pwrmgr, PWRMGR_WAKEUP_EN_REG, value); +} + +uint32_t pwrmgr_wakeup_status_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_WAKE_STATUS_REG); +} + +uint32_t pwrmgr_reset_status_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_RESET_STATUS_REG); +} + +uint32_t pwrmgr_escalate_reset_status_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_ESCALATE_RESET_STATUS_REG); +} + +uint32_t pwrmgr_wake_info_get(pwrmgr_t pwrmgr) +{ + return pwrmgr_read(pwrmgr, PWRMGR_WAKE_INFO_REG); +} + +void pwrmgr_wake_info_clear(pwrmgr_t pwrmgr, uint32_t mask) +{ + pwrmgr_write(pwrmgr, PWRMGR_WAKE_INFO_REG, mask); +} diff --git a/sw/device/lib/hal/pwrmgr.h b/sw/device/lib/hal/pwrmgr.h new file mode 100644 index 00000000..fece4f59 --- /dev/null +++ b/sw/device/lib/hal/pwrmgr.h @@ -0,0 +1,50 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Power manager interface. + +#pragma once + +#include + +#define PWRMGR_CONTROL_REG (0x14) +#define PWRMGR_CFG_CDC_SYNC_REG (0x18) +#define PWRMGR_WAKEUP_EN_REG (0x20) +#define PWRMGR_WAKE_STATUS_REG (0x24) +#define PWRMGR_RESET_STATUS_REG (0x30) +#define PWRMGR_ESCALATE_RESET_STATUS_REG (0x34) +#define PWRMGR_WAKE_INFO_REG (0x3C) + +#define PWRMGR_CONTROL_LOW_POWER_HINT_BIT (1u << 0) +#define PWRMGR_CONTROL_CORE_CLK_EN_BIT (1u << 4) +#define PWRMGR_CONTROL_IO_CLK_EN_BIT (1u << 5) +#define PWRMGR_CONTROL_MAIN_PD_N_BIT (1u << 6) +#define PWRMGR_CONTROL_MASK \ + (PWRMGR_CONTROL_LOW_POWER_HINT_BIT | PWRMGR_CONTROL_CORE_CLK_EN_BIT | \ + PWRMGR_CONTROL_IO_CLK_EN_BIT | PWRMGR_CONTROL_MAIN_PD_N_BIT) + +#define PWRMGR_WAKEUP_EN_SOC_PROXY_EXT_WKUP_REQ_BIT (1u << 0) + +#define PWRMGR_WAKE_INFO_REASONS_BIT (1u << 0) +#define PWRMGR_WAKE_INFO_FALL_THROUGH_BIT (1u << 1) +#define PWRMGR_WAKE_INFO_ABORT_BIT (1u << 2) + +typedef void *pwrmgr_t; + +#define PWRMGR_FROM_BASE_ADDR(addr) ((pwrmgr_t)(addr)) + +uint32_t pwrmgr_control_get(pwrmgr_t pwrmgr); +void pwrmgr_control_set(pwrmgr_t pwrmgr, uint32_t value); + +void pwrmgr_cfg_sync(pwrmgr_t pwrmgr); + +uint32_t pwrmgr_wakeup_enable_get(pwrmgr_t pwrmgr); +void pwrmgr_wakeup_enable_set(pwrmgr_t pwrmgr, uint32_t value); + +uint32_t pwrmgr_wakeup_status_get(pwrmgr_t pwrmgr); +uint32_t pwrmgr_reset_status_get(pwrmgr_t pwrmgr); +uint32_t pwrmgr_escalate_reset_status_get(pwrmgr_t pwrmgr); + +uint32_t pwrmgr_wake_info_get(pwrmgr_t pwrmgr); +void pwrmgr_wake_info_clear(pwrmgr_t pwrmgr, uint32_t mask); diff --git a/sw/device/lib/hal/rstmgr.c b/sw/device/lib/hal/rstmgr.c index bdb3524d..eb7c7dd6 100644 --- a/sw/device/lib/hal/rstmgr.c +++ b/sw/device/lib/hal/rstmgr.c @@ -4,9 +4,18 @@ #include "hal/rstmgr.h" #include "hal/mmio.h" -#include "hal/mocha.h" #include +uint32_t rstmgr_reset_reason_get(rstmgr_t rstmgr) +{ + return DEV_READ(rstmgr + RSTMGR_RESET_INFO_REG); +} + +void rstmgr_reset_reason_clear(rstmgr_t rstmgr, uint32_t reason) +{ + DEV_WRITE(rstmgr + RSTMGR_RESET_INFO_REG, reason); +} + void rstmgr_software_reset_request(rstmgr_t rstmgr) { DEV_WRITE(rstmgr + RSTMGR_RESET_REQ_REG, RSTMGR_RESET_REQ_TRUE); @@ -14,9 +23,9 @@ void rstmgr_software_reset_request(rstmgr_t rstmgr) bool rstmgr_software_reset_info_get(rstmgr_t rstmgr) { - if (DEV_READ(rstmgr + RSTMGR_RESET_INFO_REG) & RSTMGR_RESET_INFO_SW_RESET) { + if (rstmgr_reset_reason_get(rstmgr) & RSTMGR_RESET_INFO_SW_RESET) { // Clear the info bit before returning. - DEV_WRITE(rstmgr + RSTMGR_RESET_INFO_REG, RSTMGR_RESET_INFO_SW_RESET); + rstmgr_reset_reason_clear(rstmgr, RSTMGR_RESET_INFO_SW_RESET); return true; } return false; diff --git a/sw/device/lib/hal/rstmgr.h b/sw/device/lib/hal/rstmgr.h index 9b55aeea..e4dea095 100644 --- a/sw/device/lib/hal/rstmgr.h +++ b/sw/device/lib/hal/rstmgr.h @@ -12,11 +12,16 @@ #define RSTMGR_RESET_REQ_REG (0x4) #define RSTMGR_RESET_REQ_TRUE (kMultiBitBool4True) #define RSTMGR_RESET_INFO_REG (0x8) +#define RSTMGR_RESET_INFO_POR (0x1) +#define RSTMGR_RESET_INFO_LOW_PWR (0x2) #define RSTMGR_RESET_INFO_SW_RESET (0x4) typedef void *rstmgr_t; #define RSTMGR_FROM_BASE_ADDR(addr) ((rstmgr_t)(addr)) +uint32_t rstmgr_reset_reason_get(rstmgr_t rstmgr); +void rstmgr_reset_reason_clear(rstmgr_t rstmgr, uint32_t reason); + void rstmgr_software_reset_request(rstmgr_t rstmgr); bool rstmgr_software_reset_info_get(rstmgr_t rstmgr); diff --git a/sw/device/tests/CMakeLists.txt b/sw/device/tests/CMakeLists.txt index 3ff514d1..3cc70c9b 100644 --- a/sw/device/tests/CMakeLists.txt +++ b/sw/device/tests/CMakeLists.txt @@ -8,10 +8,12 @@ mocha_add_test(NAME test_framework_test SOURCES test_framework/smoketest.c LIBRA mocha_add_test(NAME test_framework_exception_test SOURCES test_framework/exception.c LIBRARIES ${LIBS}) mocha_add_test(NAME axi_sram_smoketest SOURCES axi_sram/smoketest.c LIBRARIES ${LIBS} FPGA) mocha_add_test(NAME axi_sram_tag_test SOURCES axi_sram/tag_test.c LIBRARIES ${LIBS} FPGA) +mocha_add_test(NAME clkmgr_smoketest SOURCES clkmgr/clkmgr_smoke_test.c LIBRARIES ${LIBS}) mocha_add_test(NAME gpio_reg_access_test SOURCES gpio/reg_access_test.c LIBRARIES ${LIBS} FPGA) mocha_add_test(NAME i2c_smoketest SOURCES i2c/smoketest.c LIBRARIES ${LIBS} FPGA) mocha_add_test(NAME mailbox_smoketest SOURCES mailbox/smoketest.c LIBRARIES ${LIBS} FPGA) mocha_add_test(NAME plic_smoketest SOURCES plic/smoketest.c LIBRARIES ${LIBS} FPGA) +mocha_add_test(NAME pwrmgr_smoketest SOURCES pwrmgr/pwrmgr_smoke_test.c LIBRARIES ${LIBS}) mocha_add_test(NAME rom_ctrl_smoketest SOURCES rom_ctrl/smoketest.c LIBRARIES ${LIBS} FPGA) # Cannot currently run this on FPGA because the boot ROM expects the test to be provided on the SPI again. mocha_add_test(NAME rstmgr_software_reset SOURCES rstmgr/software_reset.c LIBRARIES ${LIBS}) diff --git a/sw/device/tests/clkmgr/clkmgr_smoke_test.c b/sw/device/tests/clkmgr/clkmgr_smoke_test.c new file mode 100644 index 00000000..4e2dbfbd --- /dev/null +++ b/sw/device/tests/clkmgr/clkmgr_smoke_test.c @@ -0,0 +1,46 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hal/clkmgr.h" +#include "hal/mocha.h" +#include +#include + +static bool test_gateable_clock(clkmgr_t clkmgr) +{ + bool initial = clkmgr_gateable_clock_get_enabled(clkmgr, CLKMGR_GATEABLE_CLOCK_IO_PERI); + bool toggled = !initial; + + clkmgr_gateable_clock_set_enabled(clkmgr, CLKMGR_GATEABLE_CLOCK_IO_PERI, toggled); + if (clkmgr_gateable_clock_get_enabled(clkmgr, CLKMGR_GATEABLE_CLOCK_IO_PERI) != toggled) { + return false; + } + + clkmgr_gateable_clock_set_enabled(clkmgr, CLKMGR_GATEABLE_CLOCK_IO_PERI, initial); + return clkmgr_gateable_clock_get_enabled(clkmgr, CLKMGR_GATEABLE_CLOCK_IO_PERI) == initial; +} + +static bool test_hintable_clock(clkmgr_t clkmgr) +{ + bool initial = clkmgr_hintable_clock_get_hint(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN); + bool toggled = !initial; + + clkmgr_hintable_clock_set_hint(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN, toggled); + if (clkmgr_hintable_clock_get_hint(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN) != toggled) { + return false; + } + + if (toggled && !clkmgr_hintable_clock_get_enabled(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN)) { + return false; + } + + clkmgr_hintable_clock_set_hint(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN, initial); + return clkmgr_hintable_clock_get_hint(clkmgr, CLKMGR_HINTABLE_CLOCK_MAIN) == initial; +} + +bool test_main() +{ + clkmgr_t clkmgr = mocha_system_clkmgr(); + return test_gateable_clock(clkmgr) && test_hintable_clock(clkmgr); +} diff --git a/sw/device/tests/pwrmgr/pwrmgr_smoke_test.c b/sw/device/tests/pwrmgr/pwrmgr_smoke_test.c new file mode 100644 index 00000000..5d6dc936 --- /dev/null +++ b/sw/device/tests/pwrmgr/pwrmgr_smoke_test.c @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hal/pwrmgr.h" +#include "hal/mocha.h" +#include +#include + +static bool control_test(pwrmgr_t pwrmgr) +{ + uint32_t initial = pwrmgr_control_get(pwrmgr); + uint32_t expected_reset = PWRMGR_CONTROL_MAIN_PD_N_BIT; + if ((initial & PWRMGR_CONTROL_MASK) != expected_reset) { + return false; + } + + uint32_t updated = PWRMGR_CONTROL_LOW_POWER_HINT_BIT | PWRMGR_CONTROL_CORE_CLK_EN_BIT | + PWRMGR_CONTROL_IO_CLK_EN_BIT; + + pwrmgr_control_set(pwrmgr, updated); + pwrmgr_cfg_sync(pwrmgr); + if ((pwrmgr_control_get(pwrmgr) & PWRMGR_CONTROL_MASK) != updated) { + return false; + } + + pwrmgr_control_set(pwrmgr, initial); + pwrmgr_cfg_sync(pwrmgr); + return (pwrmgr_control_get(pwrmgr) & PWRMGR_CONTROL_MASK) == expected_reset; +} + +static bool wakeup_enable_test(pwrmgr_t pwrmgr) +{ + if (pwrmgr_wakeup_enable_get(pwrmgr) != 0u) { + return false; + } + + pwrmgr_wakeup_enable_set(pwrmgr, PWRMGR_WAKEUP_EN_SOC_PROXY_EXT_WKUP_REQ_BIT); + pwrmgr_cfg_sync(pwrmgr); + if (pwrmgr_wakeup_enable_get(pwrmgr) != PWRMGR_WAKEUP_EN_SOC_PROXY_EXT_WKUP_REQ_BIT) { + return false; + } + + pwrmgr_wakeup_enable_set(pwrmgr, 0u); + pwrmgr_cfg_sync(pwrmgr); + return pwrmgr_wakeup_enable_get(pwrmgr) == 0u; +} + +static bool status_test(pwrmgr_t pwrmgr) +{ + if (pwrmgr_wakeup_status_get(pwrmgr) != 0u) { + return false; + } + if (pwrmgr_reset_status_get(pwrmgr) != 0u) { + return false; + } + if (pwrmgr_escalate_reset_status_get(pwrmgr) != 0u) { + return false; + } + if (pwrmgr_wake_info_get(pwrmgr) != 0u) { + return false; + } + + pwrmgr_wake_info_clear(pwrmgr, + PWRMGR_WAKE_INFO_REASONS_BIT | PWRMGR_WAKE_INFO_FALL_THROUGH_BIT | + PWRMGR_WAKE_INFO_ABORT_BIT); + return pwrmgr_wake_info_get(pwrmgr) == 0u; +} + +bool test_main() +{ + pwrmgr_t pwrmgr = mocha_system_pwrmgr(); + return control_test(pwrmgr) && wakeup_enable_test(pwrmgr) && status_test(pwrmgr); +} diff --git a/sw/device/tests/rstmgr/software_reset.c b/sw/device/tests/rstmgr/software_reset.c index 3ca333d7..bf952088 100644 --- a/sw/device/tests/rstmgr/software_reset.c +++ b/sw/device/tests/rstmgr/software_reset.c @@ -10,15 +10,21 @@ bool test_main() { rstmgr_t rstmgr = mocha_system_rstmgr(); + uint32_t reason = rstmgr_reset_reason_get(rstmgr); - if (rstmgr_software_reset_info_get(rstmgr)) { - return true; + if (reason & RSTMGR_RESET_INFO_POR) { + rstmgr_reset_reason_clear(rstmgr, RSTMGR_RESET_INFO_POR); + rstmgr_software_reset_request(rstmgr); + + // Must wait here for reset to happen. + while (1) { + } } - // Request a reset of the system. - rstmgr_software_reset_request(rstmgr); - // Must wait here for reset to happen. - while (1) { + if (reason & RSTMGR_RESET_INFO_SW_RESET) { + rstmgr_reset_reason_clear(rstmgr, RSTMGR_RESET_INFO_SW_RESET); + return true; } + return false; }