diff options
author | Evan Lojewski <github@meklort.com> | 2020-02-26 21:12:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-26 21:12:13 -0700 |
commit | a6944445a08c729c36aa482d54ed9ee4e77a2360 (patch) | |
tree | 27ba022fa01ce1e29a303cd4999abbe68ebcd571 | |
parent | b82cd4c280bbe92012213cc2c8856546f74d6723 (diff) | |
download | bcm5719-ortega-a6944445a08c729c36aa482d54ed9ee4e77a2360.tar.gz bcm5719-ortega-a6944445a08c729c36aa482d54ed9ee4e77a2360.zip |
ape: Reset the network interface when the host driver state changes. (#45)
-rw-r--r-- | ape/main.c | 102 | ||||
-rw-r--r-- | include/APE_SHM.h | 27 | ||||
-rw-r--r-- | include/bcm5719_GEN.h | 33 | ||||
-rw-r--r-- | include/bcm5719_SHM.h | 27 | ||||
-rw-r--r-- | ipxact/SHM.xml | 22 | ||||
-rw-r--r-- | ipxact/bcm5719.xml | 34 |
6 files changed, 217 insertions, 28 deletions
@@ -107,6 +107,33 @@ void handleCommand(void) SHM.LoaderCommand.bits.Command = 0; } +void wait_for_rx(volatile DEVICE_t *device, volatile SHM_t *shm) +{ + bool waiting = true; + do + { + if (device->RxRiscStatus.bits.Halted) + { + // If the RX CPU has halted, exit out. + waiting = false; + } + + if (SHM_RCPU_SEG_SIG_SIG_RCPU_MAGIC == shm->RcpuSegSig.bits.Sig) + { + // Firmware has finished initialization. + waiting = false; + } + } while (waiting); +} + +void wait_for_all_rx() +{ + wait_for_rx(&DEVICE, &SHM); + wait_for_rx(&DEVICE1, &SHM1); + wait_for_rx(&DEVICE2, &SHM2); + wait_for_rx(&DEVICE3, &SHM3); +} + void handleBMCPacket(void) { uint32_t buffer[1024]; @@ -199,6 +226,7 @@ void checkSupply(bool alwaysReport) void __attribute__((noreturn)) loaderLoop(void) { + uint32_t host_state = SHM.HostDriverState.bits.State; // Update SHM.Sig to signal ready. SHM.SegSig.bits.Sig = SHM_SEG_SIG_SIG_LOADER; SHM.FwStatus.bits.Ready = 1; @@ -210,26 +238,48 @@ void __attribute__((noreturn)) loaderLoop(void) NCSI_handlePassthrough(); handleCommand(); checkSupply(false); - } -} -void wait_for_rx(volatile DEVICE_t *device, volatile SHM_t *shm) -{ - bool waiting = true; - do - { - if(device->RxRiscStatus.bits.Halted) + // Make sure we haven't locked up the RMU state machine. + if (APE_PERI.BmcToNcRxStatus.bits.InProgress) { - // If the RX CPU has halted, exit out. - waiting = false; + printf("BMC in prog, initRMU\n"); + initRMU(); + APE_PERI.BmcToNcRxControl.bits.ResetBad = 1; + while (APE_PERI.BmcToNcRxControl.bits.ResetBad) + { + // Wait + } } - if(SHM_RCPU_SEG_SIG_SIG_RCPU_MAGIC == shm->RcpuSegSig.bits.Sig) + if (host_state != SHM.HostDriverState.bits.State) { - // Firmware has finished initialization - waiting = false; + host_state = SHM.HostDriverState.bits.State; + if (SHM_HOST_DRIVER_STATE_STATE_UNLOAD == host_state) + { + printf("host unloaded.\n"); + wait_for_all_rx(); + NCSI_reload(ALWAYS_RESET); + } + else if (SHM_HOST_DRIVER_STATE_STATE_START == host_state) + { + printf("host started\n"); + } + else + { + printf("wol?\n"); + } } - } while (waiting); + else if (0 == APE.Mode.bits.Channel0Enable) + { + // This will trigger any time the host is unloaded. + printf("Channel0Enable == 0. Reset TX/RX\n"); + wait_for_all_rx(); + // Channel enable was cleared. + NCSI_reload(SHM_HOST_DRIVER_STATE_STATE_START != SHM.HostDriverState.bits.State ? ALWAYS_RESET : NEVER_RESET); + Network_InitTxRx(); + initRMU(); + } + } } bool handle_reset(void) @@ -274,10 +324,7 @@ bool handle_reset(void) APE.Gpio.r32 = apegpio.r32; // Wait for the RX CPU to finish executing before continuing. - wait_for_rx(&DEVICE, &SHM); - wait_for_rx(&DEVICE1, &SHM1); - wait_for_rx(&DEVICE2, &SHM2); - wait_for_rx(&DEVICE3, &SHM3); + wait_for_all_rx(); return true; } @@ -290,30 +337,29 @@ bool handle_reset(void) void __attribute__((noreturn)) __start() { - if (handle_reset() || - SHM.RcpuWritePointer.r32 > sizeof(SHM.RcpuPrintfBuffer) || - SHM.RcpuReadPointer.r32 > sizeof(SHM.RcpuPrintfBuffer) || - SHM.RcpuHostReadPointer.r32 > sizeof(SHM.RcpuPrintfBuffer) - ) + if (handle_reset() || SHM.RcpuWritePointer.r32 > sizeof(SHM.RcpuPrintfBuffer) || SHM.RcpuReadPointer.r32 > sizeof(SHM.RcpuPrintfBuffer) || + SHM.RcpuHostReadPointer.r32 > sizeof(SHM.RcpuPrintfBuffer)) { SHM.RcpuWritePointer.r32 = 0; SHM.RcpuReadPointer.r32 = 0; SHM.RcpuHostReadPointer.r32 = 0; printf("Chip Reset.\n"); + Network_InitTxRx(); + initRMU(); + + NCSI_init(); } else { printf("APE Reload.\n"); + Network_InitTxRx(); + initRMU(); + NCSI_reload(SHM_HOST_DRIVER_STATE_STATE_START != SHM.HostDriverState.bits.State ? AS_NEEDED : NEVER_RESET); } - checkSupply(true); printf("Begin APE.\n"); - NCSI_init(); - Network_InitTxRx(); - initRMU(); - loaderLoop(); } diff --git a/include/APE_SHM.h b/include/APE_SHM.h index 4795fff..e5e0ad3 100644 --- a/include/APE_SHM.h +++ b/include/APE_SHM.h @@ -1209,10 +1209,31 @@ typedef register_container RegSHMHeartbeatCount_t { } RegSHMHeartbeatCount_t; #define REG_SHM_HOST_DRIVER_STATE ((volatile APE_SHM_H_uint32_t*)0x6022021c) /* */ +#define SHM_HOST_DRIVER_STATE_STATE_SHIFT 0u +#define SHM_HOST_DRIVER_STATE_STATE_MASK 0xffffffffu +#define GET_SHM_HOST_DRIVER_STATE_STATE(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_HOST_DRIVER_STATE_STATE(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_HOST_DRIVER_STATE_STATE_START 0x1u +#define SHM_HOST_DRIVER_STATE_STATE_UNLOAD 0x2u +#define SHM_HOST_DRIVER_STATE_STATE_WOL 0x3u + + /** @brief Register definition for @ref SHM_t.HostDriverState. */ typedef register_container RegSHMHostDriverState_t { /** @brief 32bit direct register access. */ APE_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(APE_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, State, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, State, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(APE_SHM_H_uint32_t, bits) #ifdef CXX_SIMULATOR /** @brief Register name for use with the simulator. */ const char* getName(void) { return "HostDriverState"; } @@ -1224,6 +1245,12 @@ typedef register_container RegSHMHostDriverState_t { { /** @brief constructor for @ref SHM_t.HostDriverState. */ r32.setName("HostDriverState"); + bits.State.setBaseRegister(&r32); + bits.State.setName("State"); + bits.State.addEnum("Start", 0x1); + bits.State.addEnum("Unload", 0x2); + bits.State.addEnum("WOL", 0x3); + } RegSHMHostDriverState_t& operator=(const RegSHMHostDriverState_t& other) { diff --git a/include/bcm5719_GEN.h b/include/bcm5719_GEN.h index 64159a9..e9ab367 100644 --- a/include/bcm5719_GEN.h +++ b/include/bcm5719_GEN.h @@ -335,10 +335,34 @@ typedef register_container RegGENGenAsfStatusMbox_t { } RegGENGenAsfStatusMbox_t; #define REG_GEN_GEN_FW_DRIVER_STATE_MBOX ((volatile BCM5719_GEN_H_uint32_t*)0xc04) /* */ +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_SHIFT 0u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_MASK 0xffffffffu +#define GET_GEN_GEN_FW_DRIVER_STATE_MBOX_STATE(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_GEN_GEN_FW_DRIVER_STATE_MBOX_STATE(__val__) (((__val__) << 0u) & 0xffffffffu) +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_START 0x1u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_UNLOAD 0x2u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_WOL 0x3u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_SUSPEND 0x4u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_START_DONE 0x80000001u +#define GEN_GEN_FW_DRIVER_STATE_MBOX_STATE_UNLOAD_DONE 0x80000002u + + /** @brief Register definition for @ref GEN_t.GenFwDriverStateMbox. */ typedef register_container RegGENGenFwDriverStateMbox_t { /** @brief 32bit direct register access. */ BCM5719_GEN_H_uint32_t r32; + + BITFIELD_BEGIN(BCM5719_GEN_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_GEN_H_uint32_t, State, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_GEN_H_uint32_t, State, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(BCM5719_GEN_H_uint32_t, bits) #ifdef CXX_SIMULATOR /** @brief Register name for use with the simulator. */ const char* getName(void) { return "GenFwDriverStateMbox"; } @@ -350,6 +374,15 @@ typedef register_container RegGENGenFwDriverStateMbox_t { { /** @brief constructor for @ref GEN_t.GenFwDriverStateMbox. */ r32.setName("GenFwDriverStateMbox"); + bits.State.setBaseRegister(&r32); + bits.State.setName("State"); + bits.State.addEnum("Start", 0x1); + bits.State.addEnum("Unload", 0x2); + bits.State.addEnum("WOL", 0x3); + bits.State.addEnum("Suspend", 0x4); + bits.State.addEnum("Start Done", 0x80000001); + bits.State.addEnum("Unload Done", 0x80000002); + } RegGENGenFwDriverStateMbox_t& operator=(const RegGENGenFwDriverStateMbox_t& other) { diff --git a/include/bcm5719_SHM.h b/include/bcm5719_SHM.h index c7d26a3..000480b 100644 --- a/include/bcm5719_SHM.h +++ b/include/bcm5719_SHM.h @@ -1209,10 +1209,31 @@ typedef register_container RegSHMHeartbeatCount_t { } RegSHMHeartbeatCount_t; #define REG_SHM_HOST_DRIVER_STATE ((volatile BCM5719_SHM_H_uint32_t*)0xc001421c) /* */ +#define SHM_HOST_DRIVER_STATE_STATE_SHIFT 0u +#define SHM_HOST_DRIVER_STATE_STATE_MASK 0xffffffffu +#define GET_SHM_HOST_DRIVER_STATE_STATE(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_HOST_DRIVER_STATE_STATE(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_HOST_DRIVER_STATE_STATE_START 0x1u +#define SHM_HOST_DRIVER_STATE_STATE_UNLOAD 0x2u +#define SHM_HOST_DRIVER_STATE_STATE_WOL 0x3u + + /** @brief Register definition for @ref SHM_t.HostDriverState. */ typedef register_container RegSHMHostDriverState_t { /** @brief 32bit direct register access. */ BCM5719_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(BCM5719_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, State, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, State, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(BCM5719_SHM_H_uint32_t, bits) #ifdef CXX_SIMULATOR /** @brief Register name for use with the simulator. */ const char* getName(void) { return "HostDriverState"; } @@ -1224,6 +1245,12 @@ typedef register_container RegSHMHostDriverState_t { { /** @brief constructor for @ref SHM_t.HostDriverState. */ r32.setName("HostDriverState"); + bits.State.setBaseRegister(&r32); + bits.State.setName("State"); + bits.State.addEnum("Start", 0x1); + bits.State.addEnum("Unload", 0x2); + bits.State.addEnum("WOL", 0x3); + } RegSHMHostDriverState_t& operator=(const RegSHMHostDriverState_t& other) { diff --git a/ipxact/SHM.xml b/ipxact/SHM.xml index a02a7eb..d3dc11c 100644 --- a/ipxact/SHM.xml +++ b/ipxact/SHM.xml @@ -451,6 +451,28 @@ <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> <ipxact:size>32</ipxact:size> <ipxact:volatile>true</ipxact:volatile> + <ipxact:field> + <ipxact:name>State</ipxact:name> + <ipxact:description></ipxact:description> + <ipxact:bitOffset>0</ipxact:bitOffset> + <ipxact:bitWidth>32</ipxact:bitWidth> + <ipxact:access>read-write</ipxact:access> + <ipxact:enumeratedValues> + <!-- LINK: enumeratedValue: see 6.11.10, Enumeration values --> + <ipxact:enumeratedValue> + <ipxact:name>Start</ipxact:name> + <ipxact:value>1</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>Unload</ipxact:name> + <ipxact:value>2</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>WOL</ipxact:name> + <ipxact:value>3</ipxact:value> + </ipxact:enumeratedValue> + </ipxact:enumeratedValues> + </ipxact:field> </ipxact:register> <ipxact:register> <ipxact:name>WOL_SPEED</ipxact:name> diff --git a/ipxact/bcm5719.xml b/ipxact/bcm5719.xml index 60f156d..98ebb06 100644 --- a/ipxact/bcm5719.xml +++ b/ipxact/bcm5719.xml @@ -134,6 +134,40 @@ <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> <ipxact:size>32</ipxact:size> <ipxact:volatile>true</ipxact:volatile> + <ipxact:field> + <ipxact:name>State</ipxact:name> + <ipxact:description></ipxact:description> + <ipxact:bitOffset>0</ipxact:bitOffset> + <ipxact:bitWidth>32</ipxact:bitWidth> + <ipxact:access>read-write</ipxact:access> + <ipxact:enumeratedValues> + <!-- LINK: enumeratedValue: see 6.11.10, Enumeration values --> + <ipxact:enumeratedValue> + <ipxact:name>Start</ipxact:name> + <ipxact:value>1</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>Start Done</ipxact:name> + <ipxact:value>0x80000001</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>Unload</ipxact:name> + <ipxact:value>2</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>Unload Done</ipxact:name> + <ipxact:value>0x80000002</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>WOL</ipxact:name> + <ipxact:value>3</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>Suspend</ipxact:name> + <ipxact:value>4</ipxact:value> + </ipxact:enumeratedValue> + </ipxact:enumeratedValues> + </ipxact:field> </ipxact:register> <ipxact:register> <ipxact:name>GEN_FW_RESET_TYPE_MBOX</ipxact:name> |