summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Lojewski <github@meklort.com>2020-02-26 21:12:13 -0700
committerGitHub <noreply@github.com>2020-02-26 21:12:13 -0700
commita6944445a08c729c36aa482d54ed9ee4e77a2360 (patch)
tree27ba022fa01ce1e29a303cd4999abbe68ebcd571
parentb82cd4c280bbe92012213cc2c8856546f74d6723 (diff)
downloadbcm5719-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.c102
-rw-r--r--include/APE_SHM.h27
-rw-r--r--include/bcm5719_GEN.h33
-rw-r--r--include/bcm5719_SHM.h27
-rw-r--r--ipxact/SHM.xml22
-rw-r--r--ipxact/bcm5719.xml34
6 files changed, 217 insertions, 28 deletions
diff --git a/ape/main.c b/ape/main.c
index a7b43eb..2bdc663 100644
--- a/ape/main.c
+++ b/ape/main.c
@@ -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>
OpenPOWER on IntegriCloud